Policy Injection with CachingHandler and generic method.

Topics: Caching Application Block , Policy Injection Application Block
Aug 25, 2008 at 3:08 AM
I like the fact that the caching handler can keep a seperate cache for each signature for a method.

Does the generic type get included in the signature?

If not, can I extend a ICallHandler to support this?
Aug 25, 2008 at 11:52 AM
Yes, the full name for the closed generic type is included; you can take a look at the Microsoft.Practices.EnterpriseLibrary.PolicyInjection.CallHandlers.DefaultCacheKeyGenerator class for details.

Aug 26, 2008 at 4:27 AM
I've noticed that within the constructor of the CachingCallHandler that it creates the DefaultCacheKeyGenerator how can one override that behaviour to return a custom implementation.
Aug 26, 2008 at 2:02 PM
You need to create your own ICallHandler.

Aug 26, 2008 at 11:56 PM
I created a custom callhandler.

It works for non-generic methods, but for generic ones, it never gets invoked.

Do you know why?

Public Class myCacheCallHandler
    Implements Microsoft.Practices.EnterpriseLibrary.PolicyInjection.ICallHandler
    Private _cacheKey As String

    Sub New(ByVal cacheKey As String)
        _cacheKey = cacheKey
    End Sub

    Public Function Invoke(ByVal input As Microsoft.Practices.EnterpriseLibrary.PolicyInjection.IMethodInvocation, ByVal getNext As Microsoft.Practices.EnterpriseLibrary.PolicyInjection.GetNextHandlerDelegate) As Microsoft.Practices.EnterpriseLibrary.PolicyInjection.IMethodReturn Implements Microsoft.Practices.EnterpriseLibrary.PolicyInjection.ICallHandler.Invoke
        Return getNext()(input, getNext)
    End Function

    Public Property Order() As Integer Implements Microsoft.Practices.EnterpriseLibrary.PolicyInjection.ICallHandler.Order
             return 0
        End Get
        Set(ByVal value As Integer)

        End Set
    End Property

End Class
<AttributeUsage(AttributeTargets.[Class] Or AttributeTargets.[Property] Or AttributeTargets.Method)> _
Public Class myCacheCallHandlerAttribute
    Inherits HandlerAttribute

    Private _x As String

    Public Sub New(ByVal x As String)
        _x = x
    End Sub

    Public Overloads Overrides Function CreateHandler() As ICallHandler
        Return New myCacheCallHandler(_x)
    End Function
End Class

Aug 27, 2008 at 12:47 PM

I'm afraid I misunderstood your original question. No, PIAB doesn't currently support generic methods.

If you need this now (ie before this issue gets fixed), you can try updating the code for the InterceptingRealProxy and either rebuilding EntLib or creating your own copy of the remoting-based injector as a custom injector, so that instead of this:

  115             HandlerPipeline pipeline;

  116             if (memberHandlers.ContainsKey(callMessage.MethodBase))

  117             {

  118                 pipeline = memberHandlers[callMessage.MethodBase];

  119             }

  120             else

  121             {

  122                 pipeline = new HandlerPipeline();

  123             }

it does this:

  117             MethodBase keyMethodBase

  118                 = callMessage.MethodBase.IsGenericMethod && callMessage.MethodBase is MethodInfo

  119                     ? ((MethodInfo)callMessage.MethodBase).GetGenericMethodDefinition()

  120                     : callMessage.MethodBase;


  122             if (memberHandlers.ContainsKey(keyMethodBase))

  123             {

  124                 pipeline = memberHandlers[keyMethodBase];

  125             }

  126             else

  127             {

  128                 pipeline = new HandlerPipeline();

  129             }

Disclaimer: I don't know if this is what the actual fix will look like when it's done, and I've tested this change lightly (the existing unit tests and a new one for generic methods passed); the purpose of this code snippet is to provide a temporary solution to the generics issue that you may choose to consider.