Unity Interception Extension Example - TransparentProxyPolicyInjector HandlerAttribute ICallHandler [转]

Update 10/21/2008: Another name change in the latest Unity v1.2 Drop. Please see the following tutorial with the appropriate code changes: TransparentProxyInterceptor and Unity Interception Extension Example in Unity v1.2

 

Right after I created a screencast showing off the Interception Extension in Unity v1.2:

Microsoft Patterns & Practices changed the name of the RemotingPolicyInjector to the TransparentProxyPolicyInjector:

No big deal, however, all the code in the screencast still works. Just substitute TransparentProxyPolicyInjector where appropriate.

 

Unity Interception Extension Sample

As promised, here is a quick sample of the Unity Interception Extension and TransparentProxyPolicyInjector. This tutorial was written using the Unity September 29, 2008 Drop - Changeset 12582.

In this example I am still using a custom HandlerAttribute and ICallHandler just because I am not sure if using one of the Policy Injection Application Block's CallHandlers would be feasible without adding multiple instances of the assemblies. To avoid the headache, I figured I would just create a custom HandlerAttribute and ICallHandler.

My custom HandlerAttribute, NotNullAttribute, and ICallHandler, NotNullHandler, validate that the arguments passed to a method are not null. If one is null, the NotNullHandler throws an ArgumentNullException.

 

public class NotNullAttribute : HandlerAttribute

{

    public override ICallHandler CreateHandler(Microsoft.Practices.Unity.IUnityContainer container)

    {

        return new NotNullHandler();

    }

}

 

public class NotNullHandler : ICallHandler

{

    public int Order { get; set; }

 

    public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)

    {

        for (int i = 0; i < input.Inputs.Count; i++)

        {

            object target = input.Inputs[i];

            if (target == null)

            {

                ParameterInfo parameterInfo = input.Inputs.GetParameterInfo(i);

                ArgumentNullException ex = new ArgumentNullException(parameterInfo.Name);

                return input.CreateExceptionMethodReturn(ex);

            }

        }

 

        return getNext()(input, getNext);

    }

}

 

Again, you don't need to create these custom attributes and callhandlers to use the Interception Extension and TransparentProxyPolicyInjector. The Policy Injection Application Block has custom callhandlers that work with the various Enterprise Library Application Blocks. You can, for example, use the ValidationCallHandler in conjunction with the Validation Application Block and the LogCallHandler with the LoggingApplicationBlock, etc.

Now we need some code to intercept. Let's work with a barebone's ISubscriberRepository and SubscriberRepository just to make the point.

 

public interface ISubscriberRepository

{

    [NotNull]

    void Add(Subscriber subscriber);

}

 

public class SubscriberRepository : ISubscriberRepository

{

    public void Add(Subscriber subscriber)

    {

        // Do Something

    }

}

 

public class Subscriber

{

    public string EmailAddress { get; set; }

}

 

Notice the use of the NotNullAttribute on the ISubscriberRepository's Add Method. The TransparentProxyPolicyInjector will notice the attribute and return a Transparent Proxy as opposed to the real SubscriberRepository that we are going to register with Unity. Before the Add Method is invoked on the SubscriberRepository, our custom callhandler, NotNullHandler, will run first, verifying that the subscriber passed into the Add Method is not null. If it is null, it will throw an exception and the Add Method on SubscriberRepository will never run.

Now for a simple console application that registers all the appropriate classes in the UnityContainer:

 

internal class Program

{

    private static void Main(string[] args)

    {

        IUnityContainer container = new UnityContainer();

        container.AddNewExtension<Interception>();

        container.RegisterType<ISubscriberRepository, SubscriberRepository>();

        container.Configure<Interception>().SetInjectorFor<ISubscriberRepository>(

            new TransparentProxyPolicyInjector());

 

        ISubscriberRepository repository = container.Resolve<ISubscriberRepository>();

 

        try

        {

            repository.Add(null);

        }

        catch (ArgumentNullException ex)

        {

            Console.WriteLine(string.Format("Parameter {0} is null.", ex.ParamName));

        }

    }

}

 

All of this code was discussed in the screencast, which offers a bit more discussion. You can see that I added the Interception Extension to the UnityContainer as well as set the injection for the ISubscriberRepository to the TransparentProxyPolicyInjector. If you don't want to write all this code, you can add all this to a configuration section in your app.config, web.config, or custom configuration file as well.

Run the following code and you will see the following on the console screen:

 

Parameter subscriber is null.

 

Just as we expected :)


POST:http://www.pnpguidance.net/Post/UnityInterceptionExtensionExampleTransparentProxyPolicyInjectorHandlerAttributeICallHandler.aspx

posted on 2010-01-20 14:36  allenjsl  阅读(1416)  评论(0编辑  收藏  举报

导航