Mixing MEF and PIAB

The Policy Injection Application Block (PIAB) provides a way to dynamically apply cross-cutting concerns by configuration or attributes. The combination of this technique and composition using Managed Extensibility Framework (MEF) can be realized through the use of a factory method as demonstrated here. The example demonstrates PIAB by the use of a CallHandler specifically for incrementing a performance counter. This is handled by the PerformanceCounterCallHandlerAttribute found in Microsoft.Practices.EnterpriseLibrary.PolicyInjection.dll. In the example the interface ISomeService is what is exported to MEF for composition.

 

    public interface ISomeService

    {

        void TestMethod();

    }

In order to use a type with policy injection it must derive from MarshalByRefObject:

    public class SomeService : MarshalByRefObject, ISomeService

    {

        public SomeService() {}

        [PerformanceCounterCallHandler("EntLibPerfTest", "lta")]

        public void TestMethod()

        {

            Console.WriteLine(":-) Called my TestMethod"); //LOGIC

        }

    }

The parameters to the PerformanceCounterCallHandler attribute represents the performance counter category and instance name respectively. In order to allow PIAB to do its work you should retrieve the type through the static Create method on the PolicyInjection class (or Wrap it):

 

                SomeService s = PolicyInjection.Create<SomeService>();

 

MEF works with [Export] and [Import] attributes and will construct the registered export when a client asks for an implementation (according to the Creation Policy of course). Therefore it is not an option to export the type SomeService directly. Instead we create a Factory for the type that returns the type after applying registered policies for that type:

 

    public class SomeServiceFactory

    {

        [Export(typeof(ISomeService))]

        public ISomeService Instance

        {

            get

            {

                //return new SomeService();

                return PolicyInjection.Create<SomeService>()

            }

        }

    }

This solves the problem of delegating the construction to our Policy Injection Application Block, and you can simply write:

 

    class Program

    {

        static void Main(string[] args)

        {

            using (var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()))

            {

                using (var container = new CompositionContainer(catalog))

                {

                    ISomeService svc = container.GetExport<ISomeService>().Value; // wrapped

                    svc.TestMethod();

                }

            }

        }

    }

If we take a dependency in another class of this service as:

 

    [Export(typeof(MEFComposedType))]

    public class MEFComposedType

    {

        ISomeService _someservice;

        [ImportingConstructor]

        public MEFComposedType(ISomeService service)

        {

            _someservice = service;

        }

        public void Foo()

        {

            _someservice.TestMethod();

        }

    }

It will be created by our factory method and injected as expected:

 

    class Program

    {

        static void Main(string[] args)

        {

            using (var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()))

            {

                using (var container = new CompositionContainer(catalog))

                {

                    MEFComposedType mct = container.GetExportedValue<MEFComposedType>();

                    mct.Foo();

                }

            }

        }

    }

This will work fine for dependencies you can isolate, but if you rely on MEF to construct and compose more complex graphs of types it may become necessary to use the static Wrap method of the PolicyInjection before using services.

Another way to accomplish almost the same is to export the actual type AND the interfaces and use the factory to add the policy:

    [Export]

    public class SomeService : MarshalByRefObject, ISomeService

    {

        [PerformanceCounterCallHandler("EntLibPerfTest", "lta")]

        public void TestMethod()

        {

            Console.WriteLine(":-) Called my TestMethod");

        }

    }

    public class SomeServiceFactory

    {

        SomeService _someservice;

        [ImportingConstructor]

        public SomeServiceFactory(SomeService someservice)

        {

            _someservice = someservice;

        }

        [Export(typeof(ISomeService))]

        public ISomeService Instance

        {

            get

            {

                return PolicyInjection.Wrap<SomeService> (_someservice);

            }

        }

    }

This method has the unfortunate side-effect of exporting actual types to the catalog, but solves the problem of using policy injection in complex graphs of dependencies. An alternative method could be interface inheritance. Having one public Interface that other components takes dependencies on and an internal interface deriving from this would allow for the usual flexibility.