(转)MEF+Unity

http://www.dotnetspark.com/kb/4659-mef--unity-interception.aspx

MEF + Unity Interception

Posted By:Mahadesh Mahalingappa       Posted Date: August 06, 2011    Points: 200    Category: C#    URL:   

In this article I try to use MEF with Unity Framework . I am trying to build a simple app which would be extensible and at the same time would use Aspect Oriented Concept
 
 
 

 

 

Scope of this Article

In this article, I try to use MEF with Unity Framework. I am trying to build a simple app which would be extensible and at the same time would use Aspect Oriented Concept.

Prerequisites

Basic knowledge of MEF and Unity framework.

Step 1

A. Download the MEF Contrib from the site - http://mefcontrib.codeplex.com/ 

Question to be asked is why should you download MEF Contrib when you already have MEF DLLs with you. Well, the MEF DLLs do not provide us the Layer which integrates with the Unity Framework. Hence MEF Components cannot be accessed by Unity Framework and vice versa.

B. Download the Unity Application Block DLLs from the site -http://www.microsoft.com/download/en/details.aspx?id=9093

Once we have the DLLs downloaded, we can start with coding. Before coding, let's get some understanding of what we are trying here.
We are going to use MEFContrib to provide an extensibility to our application and Unity Framework so that we can bring the concept of Aspect Oriented Programming.


Unity + MEF Integration Layer is a middle component (implemented as MefContrib.Integration.Unity.dll) that combines the strength of both frameworks and allows great extensibility. Using integration layer, the developer can structure the application's backbone using Unity while leaving the extensibility part to MEF as you can see from the figure below:
image001.jpg

What the layer actually does is that it makes MEF components (i.e. components known to MEF) available to the Unity by automatically injecting them into Unity components (i.e., components registered in the Unity container), and vice versa. This "synchronization" can be either one-way or two way. In the first case, Unity will know about MEF components (but MEF will know nothing about Unity), thus Unity will be able to inject MEF components into Unity ones. The opposite synchronization, in which MEF will know about Unity's components, is also possible but is unlikely to be used. In the second scenario, both MEF and Unity know about each other, enabling both frameworks to use each other components.

Step 2

I have added all the DLLs and dependency DLLs (not necessary to add as references) required for this application as shown below:

image002.jpg

Step 3

public interface ILogger
    {
        void Write(string message);
    }

Creating the Console Logger

using System.ComponentModel.Composition;

  [Export(typeof(ILogger))]

    public class ConsoleLogger : ILogger
    {
        public void Write(string message)
        {
            Console.WriteLine(message);
        }
    }

Creating the Interceptor

The Interceptor code would look like below:


 

using Microsoft.Practices.Unity.InterceptionExtension;
using System.ComponentModel.Composition;

public class Interceptor : IInterceptionBehavior
    {
        [Import]
        public ILogger Logger { get; set; }

        public Interceptor()
        {
        }

        public IEnumerable GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
            //return null;
        }

        public IMethodReturn Invoke
        (IMethodInvocation input, GetNextInterceptionBehaviorDelegate getNext)
        {
           
            IMethodReturn msg = null;
            

            //Pre method calling
            Logger.Write("Hello World + Pre Method Calling");

           // Method is invoked 
            msg = getNext()(input, getNext);

            //Post method calling 
            Logger.Write("Hello World + Post Method Calling");
                        
            return msg;
        }

        public bool WillExecute
        {
            get 
            { 
                return true; 
            }            
        }
    } 


Create an Interface for the Application class.


 

public interface IApplication
    {
        void Run();
    }


Application class looks as below:

using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.Reflection;

public class Application : IApplication
    {
        [Import]
        public ILogger Logger { get; set; }

        public virtual void Run()
        {
            var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
            var container = new CompositionContainer(catalog);

            container.ComposeParts(this);
           
            Logger.Write("Helloworld");
            Console.ReadLine();
        }      
    }

Final Structure

image003.jpg Let's give it a run:
image004.jpg

Using Interception with Unity

Interception is a design pattern that is designed for cross-cutting concerns, issues that cut across the entire software. You can intercept a method call after the method call has been made. In short, it's a method of achieving Aspect Oriented Programming.

Unity provides support for interception through the Interception container extension.
To get an insight into what Interception is, check out this link.

VirtualMethodInterceptor

A type interceptor. It uses dynamic code generation to create a derived class that gets instantiated instead of the original, intercepted class and to hook up the call handlers.

Use

Let's discuss about the Interceptor which is the key component.
Interceptor is a class which implements the interface Microsoft.Practices.Unity.InterceptionExtension.IInterceptionBehavior.

IInterceptionBehavior

namespace Microsoft.Practices.Unity.InterceptionExtension
{
    public interface IInterceptionBehavior
    {
        bool WillExecute { get; }

        IEnumerable GetRequiredInterfaces();
        IMethodReturn Invoke(IMethodInvocation input, 
			GetNextInterceptionBehaviorDelegate getNext);
    }
}

Resolving the Dependencies for the Unity Container

When a call is made to the Resolve method on the Unity container, dependencies are fetched using theGetRequiredInterfaces() method. So this method acts as a Dependency Resolver.

public IEnumerable GetRequiredInterfaces()
        {
            return Type.EmptyTypes;
        }

Turning the Interceptor On and Off

This property lets the Interceptor know whether it has to intercept the method call or not. If WillExecute istrue, the interceptor would be activated, a false would deactivate the interceptor.

public bool WillExecute
        {
            get 
            { 
                return true; 
            }            
        }

public IMethodReturn Invoke(IMethodInvocation input, 
		GetNextInterceptionBehaviorDelegate getNext)
  {           
      IMethodReturn msg = null;
       
       //Pre method calling
       Logger.Write("Hello World + Pre Method Calling");
           
       msg = getNext()(input, getNext); <= Method invoked

       //Post method calling 
       Logger.Write("Hello World + Post Method Calling");
            
       Console.ReadLine();
       return msg;
   }


We can debug and check out how the method behaves. The msg returns with an Exception of null which confirms that the Interception call is successfully completed.

image005.jpg

Conclusion

In this example, I tried to keep things simple by concentrating on creating an application which would make extensibility work with AOP.

posted on 2015-08-04 13:38  oyl  阅读(323)  评论(0编辑  收藏  举报

导航