Enterprise library migration from 4.1 to 5.0

Oct 4, 2010 at 10:58 PM

I'm migrating an application which uses enterprise library 4.1 to 5.0. I followed the migration guide provided for ent lib 5.0. However I'm still receiving the following error. Although the LogWriter is an abstract class in v5.0, its been called through the policy injection app block.

Does anyone came across this before?

Test method Mcd.Common.Delegate.UnitTest.UnityWrapperTest.PolicyInjectionTest threw exception:  Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the dependency failed, type = "Mcd.Common.Delegate.UnitTest.ITestInterface", name = "TestMap".Exception occurred while: Calling constructor Microsoft.Practices.Unity.InterceptionExtension.PolicyInjectionBehavior(Microsoft.Practices.Unity.InterceptionExtension.CurrentInterceptionRequest interceptionRequest, Microsoft.Practices.Unity.InterceptionExtension.InjectionPolicy[] policies, Microsoft.Practices.Unity.IUnityContainer container).Exception is: ResolutionFailedException - Resolution of the dependency failed, type = "Microsoft.Practices.Unity.InterceptionExtension.ICallHandler", name = "Logging Handler-Logging Policy".Exception occurred while: while resolving.Exception is: InvalidOperationException - The type LogWriter cannot be constructed. You must configure the container to supply this value.-----------------------------------------------At the time of the exception, the container was:
  Resolving Microsoft.Practices.EnterpriseLibrary.Logging.PolicyInjection.LogCallHandler,Logging Handler-Logging Policy (mapped from Microsoft.Practices.Unity.InterceptionExtension.ICallHandler, Logging Handler-Logging Policy)  Resolving parameter "logWriter" of constructor Microsoft.Practices.EnterpriseLibrary.Logging.PolicyInjection.LogCallHandler(Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter logWriter)    Resolving Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter,(none)
-----------------------------------------------At the time of the exception, the container was:
  Resolving Mcd.Common.Delegate.UnitTest.TestClass,TestMap (mapped from Mcd.Common.Delegate.UnitTest.ITestInterface, TestMap)    Resolving Microsoft.Practices.Unity.InterceptionExtension.PolicyInjectionBehavior,(none)    Calling constructor Microsoft.Practices.Unity.InterceptionExtension.PolicyInjectionBehavior(Microsoft.Practices.Unity.InterceptionExtension.CurrentInterceptionRequest interceptionRequest, Microsoft.Practices.Unity.InterceptionExtension.InjectionPolicy[] policies, Microsoft.Practices.Unity.IUnityContainer container) --->  Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the dependency failed, type = "Microsoft.Practices.Unity.InterceptionExtension.ICallHandler", name = "Logging Handler-Logging Policy".Exception occurred while: while resolving.Exception is: InvalidOperationException - The type LogWriter cannot be constructed. You must configure the container to supply this value.

 

Oct 5, 2010 at 1:10 AM

I'm assuming this exception occurs when you're calling PolicyInjection.Create or PolicyInjection.Wrap?  Could you post the constructor of the class that you're trying to use in that PolicyInjection code?

 

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

Oct 5, 2010 at 1:47 AM

Thanks for the reply.

The application uses an UnityWrapper class for creating an instance of the actual object. Code for this method is as follows,

 

        public static T CreateInstance(string mapName, IUnityContainer container, InterceptorType interceptorType)
        {
            //Get the PIAB settings from the configuration file
            IConfigurationSource configSource = ConfigurationSourceFactory.Create();
            PolicyInjectionSettings settings = (PolicyInjectionSettings)configSource.GetSection(PolicyInjectionSettings.SectionName);
            // Apply PIAB settings, if any, to the container
            if (settings != null)
            {
                settings.ConfigureContainer(container, configSource);
            }

            // Add interception
            container.AddNewExtension();
            // Set the interceptor for the container based on the interceptor type
            switch (interceptorType)
            {
                case InterceptorType.TransparentProxy:
                    container.Configure().SetInterceptorFor(mapName, new TransparentProxyInterceptor());
                    break;
                case InterceptorType.Interface:
                    container.Configure().SetInterceptorFor(mapName, new InterfaceInterceptor());
                    break;
                case InterceptorType.VirtualMethod:
                    container.Configure().SetInterceptorFor(mapName, new VirtualMethodInterceptor());
                    break;
            }

            return container.Resolve(mapName);
        }
    }
I have the following config sections in the configuration file.
  <policyInjection>
    <policies>
      <add name="Logging Policy">
        <matchingRules>
          <add type="Microsoft.Practices.EnterpriseLibrary.PolicyInjection.MatchingRules.NamespaceMatchingRule, Microsoft.Practices.EnterpriseLibrary.PolicyInjection" name="Namespace Matching Rule">
            <matches>
              <add match="Mcd.Common.Delegate.UnitTest.*" ignoreCase="false" />
            </matches>
          </add>
        </matchingRules>
        <handlers>
          <add name="Logging Handler" type="Microsoft.Practices.EnterpriseLibrary.Logging.PolicyInjection.LogCallHandler, Microsoft.Practices.EnterpriseLibrary.Logging"  logBehavior="BeforeAndAfter" beforeMessage="Before" afterMessage="After" includeParameterValues="true" includeCallTime="true" includeCallStack="false" severity="Information">
            <categories>
              <add name="Audit Category" />
            </categories>
          </add>          
        </handlers>
      </add>
    </policies>
  </policyInjection>

  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <alias alias="testContract" type="Mcd.Common.Delegate.UnitTest.ITestInterface, Mcd.Common.Delegate.UnitTest" />
    <alias alias="testConcrete" type="Mcd.Common.Delegate.UnitTest.TestClass, Mcd.Common.Delegate.UnitTest" />
    <alias alias="testConcreteMarshal" type="Mcd.Common.Delegate.UnitTest.TestMarshal, Mcd.Common.Delegate.UnitTest" />

      <container name="TestContainer">
          <register type="testContract" mapTo="testConcrete" name="TestMap"/>
          <register type="testConcreteMarshal" name="TestMapMarshal"/>
      </container>
  </unity>




  

 

Oct 5, 2010 at 1:53 AM
Edited Oct 5, 2010 at 2:03 AM

In your container.AddNewExtension() call, did you add the EnterpriseLibraryCoreExtension?  If not, try adding it first before the Interception extension.

By the way, you can opt not to include those codes which configures the policy injection settings.  You can do it the easier way by adding the PolicyInjectionBehavior.

 

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

Oct 5, 2010 at 4:08 PM

I have removed the policy injection config section and the code for policy injection settings. The unity config section is updated as below.

  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />
    
    <alias alias="testContract" type="Mcd.Common.Delegate.UnitTest.ITestInterface, Mcd.Common.Delegate.UnitTest" />
    <alias alias="testConcrete" type="Mcd.Common.Delegate.UnitTest.TestClass, Mcd.Common.Delegate.UnitTest" />
    <alias alias="testConcreteMarshal" type="Mcd.Common.Delegate.UnitTest.TestMarshal, Mcd.Common.Delegate.UnitTest" />

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

        <interception>
          <policy name="Logging Policy">
            <matchingRule name="Namespace Matching Rule" type="NamespaceMatchingRule">
              <constructor>
                <param name="namespaceName" value="Mcd.Common.Delegate.UnitTest.*"></param>
              </constructor>
            </matchingRule>
            <callHandler name="Logging Handler" type="Microsoft.Practices.EnterpriseLibrary.Logging.PolicyInjection.LogCallHandler"></callHandler>
          </policy>
        </interception>
        
          <register type="testContract" mapTo="testConcrete" name="TestMap"/>
          <register type="testConcreteMarshal" name="TestMapMarshal"/>
      </container>
  </unity>

Here I'm unable to specify the logging categories. Also now its throwing the following error. 
Test method Mcd.Common.Delegate.UnitTest.UnityWrapperTest.PolicyInjectionTest threw exception:  System.InvalidOperationException: The type name or alias Microsoft.Practices.EnterpriseLibrary.Logging.PolicyInjection.LogCallHandler could not be resolved. Please check your configuration file and verify this type name..

Am I missing anything here...

Thanks.

Oct 5, 2010 at 5:01 PM

I have modified the configuration as follows, however I couldn't find a way to specify the category for the log handler. Anyone have any examples or know how to specify the categories?

  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />
    
    <alias alias="testContract" type="Mcd.Common.Delegate.UnitTest.ITestInterface, Mcd.Common.Delegate.UnitTest" />
    <alias alias="testConcrete" type="Mcd.Common.Delegate.UnitTest.TestClass, Mcd.Common.Delegate.UnitTest" />
    <alias alias="testConcreteMarshal" type="Mcd.Common.Delegate.UnitTest.TestMarshal, Mcd.Common.Delegate.UnitTest" />

    <namespace name="Microsoft.Practices.EnterpriseLibrary.Logging.PolicyInjection" />
    <assembly name="Microsoft.Practices.EnterpriseLibrary.Logging" />

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

        <interception>
          <policy name="Logging Policy">
            <matchingRule name="Namespace Matching Rule" type="NamespaceMatchingRule">
              <constructor>
                <param name="namespaceName" value="Mcd.Common.Delegate.UnitTest.*"></param>
              </constructor>
            </matchingRule>
            <callHandler name="Logging Handler" type="LogCallHandler">
              <constructor>
              </constructor>
            </callHandler>
          </policy>
        </interception>

        <register type="testContract" mapTo="testConcrete" name="TestMap">
          <policyInjection/>
        </register>
          <register type="testConcreteMarshal" name="TestMapMarshal"/>
      </container>
  </unity>

Oct 6, 2010 at 9:20 AM

I posted my answer in the thread you created in the Unity forum.

By the way, if you don't like the idea there of creating a custom type converter, what you want is also possible by defining your policy in the policy injection settings itself.  Adding the PolicyInjectionBehavior when registering the type you want will produce the same behavior. 

 

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

Oct 6, 2010 at 4:16 PM

Sarah,

Thanks for the reply. If I'm using the same policy injection behavior, would it be possible to inject the PolicyInjectionBehavior through the configuration file?

Let me know if there are any documentation relates to this..

Oct 7, 2010 at 1:50 AM
Edited Oct 7, 2010 at 1:51 AM

You're configuring a type to use the PolicyInjectionBehavior using the <policyInjection /> element.  Although I'm afraid I didn't get your question.  Could you further clarify it?

 

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

Oct 8, 2010 at 2:36 AM

I would like to use the same policy injection settings section in the configuration file (of course I need to change the call handlers and the namespaces) and through unity configuration section I want to use the same policies.

I tried with the following unity configuration, but it didn't work. Do I need to change anything here? It will be helpful if you can give a sample configuration section.

 

  <unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />

    <alias alias="testContract" type="Mcd.TestApp.ITestInterface, Mcd.TestApp" />
    <alias alias="testConcrete" type="Mcd.TestApp.TestClass, Mcd.TestApp" />

    <container name="TestContainer">
      
      <register type="testContract" mapTo="testConcrete" name="TestMap">
        <policyInjection/>
      </register>

    </container>
  </unity>

 

Oct 8, 2010 at 2:51 AM

You need to specify the type of intercetor:

<register type="testContract" mapTo="testConcrete" name="TestMap">
        <interceptor type="InterfaceInterceptor"/>
        <policyInjection/>
</register>

To decide which interceptor to use, refer to this section in the documentation.

 

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

Oct 8, 2010 at 10:26 PM

Thanks for the information. I have referenced all the ent lib 5.0 dlls in the project. However, I'm encountering the following error while running the application.

Could not load file or assembly 'Microsoft.Practices.Unity.Interception, Version=1.2.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The located assembly's manifest definition does not match the

assembly reference. (Exception from HRESULT: 0x80131040)

I have changed the references to all unity 2.0 dlls. Is there anything I'm missing here?

 

 

Oct 8, 2010 at 11:42 PM

This happens a lot based on posts here. Inevitably the answer turns out to be one DLL that didn't get it's assembly reference updated somewhere.

You might want to try turning on the fusion log viewer (fuslogvw), that should help track down which DLL is referencing the old interception bits.