Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.RegisterHttpBinaryChannel()
           _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()
like image 267
TaylorOtwell Avatar asked Feb 23 '26 10:02

TaylorOtwell


1 Answers

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); }
}
like image 186
Marc Gravell Avatar answered Feb 24 '26 23:02

Marc Gravell



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!