How to use generic method to replace duplicated properties?
Currently my code has the following properties:
Private _queueRetriever As Services.IQueueRetriever
Public ReadOnly Property QueueRetriever As Services.IQueueRetriever
Get
If _queueRetriever Is Nothing Then
RemotingSetup.RegisterH开发者_运维问答ttpBinaryChannel()
_queueRetriever = RemotingFactory.CreateProxy(Of Services.IQueueRetriever)(Options.DevLocal)
End If
Return _queueRetriever
End Get
End Property
Private _queueCountRetriever As Services.IQueueCounter
Public ReadOnly Property QueueCounter As Services.IQueueCounter
Get
If _queueCountRetriever Is Nothing Then
RemotingSetup.RegisterHttpBinaryChannel()
_queueCountRetriever = RemotingFactory.CreateProxy(Of Services.IQueueCounter)(Options.DevLocal)
End If
Return _queueCountRetriever
End Get
End Property
As you can see, the code is essentially the same for both properties. Only the types are different. I'm not very experienced in generic methods, but I feel like I should be able to make this code more DRY using generics. Can it be done or is this not a job for generic methods?
EDIT
Building on Marc's answer, I came up with the following:
Protected Services As New Dictionary(Of Type, Object)
Protected Function CreateService(Of T)() As T
If Not Services.ContainsKey(GetType(T)) Then
RemotingSetup.RegisterHttpBinaryChannel()
Services.Add(GetType(T), RemotingFactory.CreateProxy(Of T)(Options.DevLocal))
End If
Return DirectCast(Services(GetType(T)), T)
End Function
Which, of course, can be used like so:
Me.CreateService(Of IService).Foo()
You could do (and apologies for switching into C#, but my VB skills lack the subtlety here - I'm sure it works fine in VB too though)
private T GetProxy<T>(ref T field) where T : class {
if(field == null) {
RemotingSetup.RegisterHttpBinaryChannel();
field = RemotingFactory.CreateProxy<T>(Options.DevLocal);
}
return field;
}
with:
private Services.IQueueCounter queueCounter;
public Services.IQueueCounter QueueCounter {
get { return GetProxy(ref queueCounter); }
}
private Services.IQueueRetriever queueRetriever;
public Services.IQueueRetriever QueueRetriever {
get { return GetProxy(ref queueRetriever); }
}
You could make a private generic method that gives you back the appropriate channel, but in this case you basically would replace 2 lines of code with 1 line of code and the a two line method call. It may not be worth the effort, other than if you add a third type of channel you would save yourself the danger of in the third case forgetting the RemotingSetup.RegisterHttpBinaryChannel
line.
You can't create generic properties in .Net
What you could do, is create a generic method to be called in the Get:
Private _queueCountRetriever As Services.IQueueCounter
Public ReadOnly Property QueueCounter As Services.IQueueCounter
Get
Return MyGet(Of QueueCounter ,IQueueCounter )(_queueCountRetriever)
End Get
End Property
Private Function MyGet(Of T As IT, IT)(ByRef propertyVar As T ) As IT
If propertyVar Is Nothing Then
RemotingSetup.RegisterHttpBinaryChannel()
propertyVar = RemotingFactory.CreateProxy(Of IT)(Options.DevLocal)
End If
End Function
精彩评论