Building a simple example with Unity Interception

Topics: General discussion, Logging Application Block
Mar 23, 2012 at 3:28 PM
Edited Mar 23, 2012 at 3:28 PM

Hi guys, 

i'm having trobule with (I guess) one of the simplest things to do with no luck and I am really stuck with what should I do. 

I'm just evaluating entlib + unity + interception and I'm trying to build a sample application that would put 2 entries in the log file, one before the method is called, one after. As far as I get is getting exception: The type LogWriter cannot be constructed. You must configure the container to supply this value.

This error is related with the LogCallHandler (if I remove it, everything works fine, nothing is logged of course). 

I guess the best is to include my files, so here it is:

1. app.config

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging" requirePermission="true" />
    <section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration"/>
  </configSections>
  <loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
    <listeners>
      <add name="Rolling Flat File Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.RollingFlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging"
        listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.RollingFlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging"
        fileName="rolling.log" formatter="Text Formatter" />
    </listeners>
    <formatters>
      <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging"
        template="Timestamp: {timestamp}{newline}&#xA;Message: {message}{newline}&#xA;Category: {category}{newline}&#xA;Priority: {priority}{newline}&#xA;EventId: {eventid}{newline}&#xA;Severity: {severity}{newline}&#xA;Title:{title}{newline}&#xA;Machine: {localMachine}{newline}&#xA;App Domain: {localAppDomain}{newline}&#xA;ProcessId: {localProcessId}{newline}&#xA;Process Name: {localProcessName}{newline}&#xA;Thread Name: {threadName}{newline}&#xA;Win32 ThreadId:{win32ThreadId}{newline}&#xA;Extended Properties: {dictionary({key} - {value}{newline})}"
        name="Text Formatter" />
    </formatters>
    <categorySources>
      <add switchValue="All" name="General">
        <listeners>
          <add name="Rolling Flat File Trace Listener" />
        </listeners>
      </add>
    </categorySources>
    <specialSources>
      <allEvents switchValue="All" name="All Events">
        <listeners>
          <add name="Rolling Flat File Trace Listener" />
        </listeners>
      </allEvents>
      <notProcessed switchValue="All" name="Unprocessed Category">
        <listeners>
          <add name="Rolling Flat File Trace Listener" />
        </listeners>
      </notProcessed>
      <errors switchValue="All" name="Logging Errors &amp; Warnings">
        <listeners>
          <add name="Rolling Flat File Trace Listener" />
        </listeners>
      </errors>
    </specialSources>
  </loggingConfiguration>
  <unity>
    <sectionExtension type="Microsoft.Practices.Unity.InterceptionExtension.Configuration.InterceptionConfigurationExtension, Microsoft.Practices.Unity.Interception.Configuration" />
    <alias alias="Person" type="UnityInterceptionSample.Person, UnityInterceptionSample"/>
    <alias alias="IPerson" type="UnityInterceptionSample.IPerson, UnityInterceptionSample"/>
    <container>
      <extension type="Interception" />
      <register type="IPerson" mapTo="Person">
        <interceptor type="TransparentProxyInterceptor" />
        <policyInjection />
      </register>
    </container>
  </unity>
</configuration>

2. IPerson.cs

using Microsoft.Practices.EnterpriseLibrary.Logging.PolicyInjection;

namespace UnityInterceptionSample
{
    public interface IPerson
    {
        string FirstName { get; set; }
        string LastName { get; set; }

        [LogCallHandler(AfterMessage = "*** After ***",
            BeforeMessage = "*** Before ***",
            LogBeforeCall = true,
            LogAfterCall = true)]
        string GetFullName();
    }
}

3. Person.cs

namespace UnityInterceptionSample
{
    public class Person : IPerson
    {
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string GetFullName()
        {
            return FirstName + " " + LastName;
        }
    }
}

4. Container.cs

 

using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;

namespace UnityInterceptionSample
{
    public sealed class Container
    {
        private static readonly IUnityContainer container;

        static Container()
        {
            container = new UnityContainer().LoadConfiguration();
        }

        public static T GetInstance<T>()
        {
            return container.Resolve<T>();
        }
    }
}

5. Program.cs

 

 

namespace UnityInterceptionSample
{
    class Program
    {
        static void Main(string[] args)
        {
            var person = Container.GetInstance<IPerson>();
            person.FirstName = "First";
            person.LastName = "Last";
            string fullName = person.GetFullName();
        }
    }
}

 

Any idea?

Thanks

 

Mar 23, 2012 at 4:04 PM

You need to add the EnterpriseLibraryCoreExtension to the Unity container:

static Container()
{
    container = new UnityContainer().LoadConfiguration();
    container.AddNewExtension<EnterpriseLibraryCoreExtension>();
}

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

Mar 26, 2012 at 8:24 AM

Thanks for your reply.

That solved the problem, logging is working correctly.

I guess that the (MSDN) documentation in this case should be revisited, as I have spent whole day trying to find out reason to this problem and I have not seen any example with the extension you have specified. 

Once again, thanks for your help, the problem is solved and logging is working correctly ...

Mar 27, 2012 at 12:47 AM

Glad to hear it's working.  Do you have a specific URL in mind or just generally MSDN didn't help? 

The rule of thumb is that if you are managing the container yourself then you will need to add the EnterpriseLibraryCoreExtension but if you are using the EnterpriseLibraryContainer then it gets setup for you by default.

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

Mar 27, 2012 at 7:00 AM

I spent some time going through documentation in MSDN for Unity/Policy Injection/Interception but I didn't find any example with EnterpriseLibraryCoreExtension applied to the unity container. I guess that for example this (http://msdn.microsoft.com/en-us/library/ff660918(v=pandp.20).aspx) article could at least mention something like that. 

Maybe a from-scratch-walkthrough example of setting up the interception with logging handler applied could be a way to go ...