Configure Matching Rule using Unity2.0 don't work

Topics: Building and extending application blocks, Enterprise Library Core, Exception Handling Application Block, General discussion, Policy Injection Application Block
Jan 17, 2012 at 7:44 AM
Edited Jan 17, 2012 at 7:46 AM

Hi,

I want to attach a custom call handler to all methods/properties of a namespace. So I try to configure NamespaceMatchingRule. I try to configure the matching rule but don't get success. IN My project's, I have following items

1) NonNegativeCallHandler implementing ICallHandler.  (Namespace is MatchingRuleUsingUnity)

2) NonNegativeCallHandlerAttribute inherited from HandlerAttribute. (Namespace is MatchingRuleUsingUnity)

3) ICalculator & Calculator classes:

 

  public interface ICalculator {

 

 

[NonNegativeCallHandler]

 

 

 

    Int32 Sum(Int32 x, Int32 y);
  [NonNegativeCallHandler]
    Int32 Sub(Int32 x, Int32 y);
  }


  public class Calculator : ICalculator {

    public Int32 Sum(Int32 x, Int32 y) {
      if (x == 0 && y == 0)
        throw new Exception("Operands are zero.");
      return x + y;
    }

    public Int32 Sub(Int32 x, Int32 y) {
      if (x == 0 && y == 0)
        throw new InvalidOperationException("Operands are zero.");
      return x - y;
    }

}

 

My Configuration file is :- 

 

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
  </configSections>

  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <assembly name="MatchingRuleUsingUnity"/>
    <namespace name="MatchingRuleUsingUnity, MatchingRuleUsingUnity"/>
    <alias alias="Calculator" type="MatchingRuleUsingUnity.Calculator, MatchingRuleUsingUnity"/>
    <alias alias="ICalculator" type="MatchingRuleUsingUnity.ICalculator, MatchingRuleUsingUnity"/>

    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration"/>

    <container>
      <extension type="Interception" />

      <register type="ICalculator" mapTo="Calculator">
        <interceptor type="TransparentProxyInterceptor" />
        <interceptionBehavior type="PolicyInjectionBehavior" />
      </register>

      <interception>
        <policy name="non-negative">
          <matchingRule name="rule1"
            type="TypeMatchingRule">
            <constructor>
              <param name="typeName" value="ICalculator" />
            </constructor>
          </matchingRule>
          <matchingRule name="rule2"
            type="MemberNameMatchingRule">
            <constructor>
              <param name="namesToMatch">
                <array type="string[]">
                  <value value="Sub" />
                </array>
              </param>
            </constructor>
          </matchingRule>
          <callHandler name="handler1"
            type="MatchingRuleUsingUnity.NonNegativeCallHandler, MatchingRuleUsingUnity">
            <lifetime type="singleton" />
          </callHandler>
        </policy>
      </interception>

    </container>
  </unity>
</configuration>

 

But custom call handler NonNegativeCallHandler doesn't call on any of the ICalculator interface method. 

NonNegativeCallHandleAttribute.cs:-

namespace MatchingRuleUsingUnity {

  public class NonNegativeCallHandlerAttribute : HandlerAttribute {
    public override ICallHandler CreateHandler(IUnityContainer container) {
      return new NonNegativeCallHandler();
    }
  }
}

NonNegativeCallHandler.cs

namespace MatchingRuleUsingUnity {


  public class NonNegativeCallHandler : ICallHandler {

    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext) {

      Console.WriteLine("Before {0} Method call", input.MethodBase.Name);
      // Perform the operation
      var methodReturn = getNext().Invoke(input, getNext);
      // Method failed, go ahead
      if (methodReturn.Exception != null)
        return methodReturn;
      // If the result is negative, then throw an exception
      var result = (Int32)methodReturn.ReturnValue;
      if (result < 0) {
        var exception = new ArgumentException("...");
        var response = input.CreateExceptionMethodReturn(exception);
        // Return exception instead of original return value
        return response;
      }
      Console.WriteLine("After {0} Method call", input.MethodBase.Name);
      return methodReturn;
    }

    public int Order {
      get;
      set;
    }

  }
}


Jan 17, 2012 at 8:14 AM

Your code seems to be working OK for me.  How are you instantiating your objects.  It should look like this:

            IUnityContainer container = new UnityContainer();
            container.LoadConfiguration();
            var calc = container.Resolve<ICalculator>();
            var i = calc.Sum(2, 1);

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 

Jan 17, 2012 at 10:00 AM

Hi,

Thanks for the reply. Yes, I am doing in the same way. But still custom call handler doesn't call.

I don't get any error during object initiation.

Jan 17, 2012 at 11:24 AM

Try changing

 <namespace name="MatchingRuleUsingUnity, MatchingRuleUsingUnity"/>
to
<namespace name="MatchingRuleUsingUnity"/>

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com 
Jan 20, 2012 at 4:44 AM

Hi Randy,

Thanks for the reply. You answer works for me.