EntLib 5/Unity 2: How do I configure policy injection with Unity interception

Apr 16, 2010 at 2:36 AM

Hi,

I’m currently playing with the Ent Lib 5.0 Beta 2 trying to create a proof of concept using the Microsoft.Practices.EnterpriseLibrary.Logging.PolicyInjection.LogCallHandler or any other log handler to work with the new Unity 2 configuration file schema.  The help documentation says “Enterprise Library contains a series of prebuilt call handlers that you can use with Unity interception. These handlers use the other blocks in Enterprise Library to implement common crosscutting concerns such as logging, ...”  However I can’t get it to work and I can’t find any examples other than the “GlobalCountCallHandler” which isn’t very helpful.  Anyone have any examples or know how to get the configuration below to work? 

Currently my unity configuration schema is as follows...the only part I can’t figure out is where you see the big ?

<unity>

    <aliases>

      <add alias="IUnityTest" type="HttpService.IUnityTest, HttpService" />

      <add alias="UnityTest" type="HttpService.UnityTest, HttpService" />

    </aliases>

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

 

    <container>

      <extension type="Interception" />

     

      <register type="IUnityTest" mapTo="UnityTest" >

        <interceptor type="VirtualMethodInterceptor"/>

      </register>

      <interception>

        <policy name="Policy">

            <matchingRule type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.MemberNameMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection, Version=5.0.315.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"

                name="Member Name Matching Rule">

                ?I want to have a LogCallHandler here

            </matchingRule>

            <callHandler>

              ?>I want to have the LogCallHandler here

            </callHandler>

        </policy>

      </interception>

    </container>

  </unity>

Thanks in advance,

Jason

Apr 17, 2010 at 6:23 PM

Something like this should work (I haven't actually tried it yet). Notice the other important change - the <policyInjection /> child element on the registration. You need to explicitly enable policy injection now.

 

<unity>
    <alias alias="IUnityTest" type="HttpService.IUnityTest, HttpService" />
    <alias alias="UnityTest" type="HttpService.UnityTest, HttpService" />

    <namespace name="Microsoft.Practices.EnterpriseLibrary.Logging.PolicyInjection" />
    <assembly name="Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.315.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />
 
    <container>
      <extension type="Interception" />

      <register type="IUnityTest" mapTo="UnityTest" >
        <interceptor type="VirtualMethodInterceptor"/>
        <policyInjection />
      </register>

      <interception>
        <policy name="Policy">
            <matchingRule type="MemberNameMatchingRule" name="Member Name Matching Rule">
              <constructor>
                <param name="nameToMatch" value="whateverMethodHere" />
              </constructor>
            </matchingRule>
            <callHandler type="LogCallHandler" name="logging handler">
              <constructor>
                <param name="logWriter" />
                <!-- set these values to whatever you need -->
                <param name="eventId" value="200" />
                <param name="logBeforeCall" value="false" />
                <param name="logAfterCall" value="true" />
                <param name="beforeMessage" value="" />
                <param name="afterMessage" value="Method call completed" />
                <param name="includeParameters" value="true" />
                <param name="includeCallStack" value="false" />
                <param name="includeCallTime" value="true" />
                <param name="priority" value="-1" />
              </constructor>
            </callHandler>
        </policy>
      </interception>
    </container>
</unity>

Apr 19, 2010 at 3:17 PM

Thanks for the reply ctavares.  It definitely pointed me in the right direction.  I got it to work, but I had to make a slight change to the callHandler section because Unity didn't like the fact that there is no value for logWriter.  Thus the following config works.

<unity>
    <aliases>
      <add alias="IUnityTest" type="HttpService.IUnityTest, HttpService" />
      <add alias="UnityTest" type="HttpService.UnityTest, HttpService" />
    </aliases>
    <namespace name="Microsoft.Practices.EnterpriseLibrary.Logging.PolicyInjection" />
    <assembly name="Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.315.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />

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

    <container>
      <extension type="Interception" />
      
      <register type="IUnityTest" mapTo="UnityTest" >
        <interceptor type="VirtualMethodInterceptor"/>
        <policyInjection />
      </register>
      <interception>
        <policy name="Policy">
          <matchingRule type="MemberNameMatchingRule" name="Member Name Matching Rule">
            <constructor>
              <param name="nameToMatch" value="GetMessage" />
            </constructor>
          </matchingRule>
          <callHandler type="LogCallHandler" name="logging handler">
            <constructor>
            </constructor>
            <property name="EventId" value="123" />
            <property name="LogBeforeCall" value="true" />
            <property name="LogAfterCall" value="true" />
            <property name="BeforeMessage" value="Method call started" />
            <property name="AfterMessage" value="Method call completed" />
            <property name="IncludeParameters" value="true" />
            <property name="IncludeCallStack" value="false" />
            <property name="IncludeCallTime" value="true" />
            <property name="Priority" value="-1" />
          </callHandler>
        </policy>
      </interception>

    </container>
  </unity>

Apr 19, 2010 at 7:29 PM

Ok, so you must be using a separate Unity container from the Entlib one, then? That would make sense, the container you're using wouldn't be able to resolve LogWriter because it doesn't have the Entlib configuration.

You can use a single container, and load both entlib and your configuration into it, like so:

IUnityContainer container = new UnityContainer()
    .AddNewExtension<EnterpriseLibraryCoreExtension>()
    .LoadConfiguration();

That would initialize both entlib and load your config file. Then the config I gave should work. Of course, I still haven't actually tried it. :-)

 

Oct 5, 2010 at 4:49 PM

I need to specify a category along with the log handler. How can I do that?

Thanks..

 

Oct 5, 2010 at 6:24 PM

Categories is a property on the call handler as documented on msdn.

Oct 5, 2010 at 6:57 PM

Thanks for the reply. Actually I have gone through this documentation. I need to specify the category in the configuration file.

For an example I have a logging category such as "Audit Category". How can I specify this category under the call handler specification?

 

Oct 5, 2010 at 6:59 PM

For example can I tried to specify the category as,

<property name="Categories" value="Audit Category" />
This doesn't work and throws an error.

Oct 14, 2010 at 6:39 AM

Answered in this thread.

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com