I suspect Chris Tavares is enjoying changing the name of the interceptor in Unity v1.2 just to make me keep updating my examples :) That's okay, I probably deserve it!
This is one of the reasons I often don't do examples before a product is released. There are often breaking changes in the early drops and hence one is left with the option of either keeping the erroneous code on the web or making updates over and over again to make sure everything is accurate.
[Aside: By the way, this is one of the reasons I stopped writing tutorials on the ASP.NET MVC Framework. It kept changing way to much from preview-to-preview. I bet 80% of the examples out there don't work anymore or are no longer a good practice now that the ASP.NET MVC Framework has just been released in beta.]
The interceptor in Unity v1.2 has changed from the RemotingPolicyInjector to the TransparentProxyPolicyInjector to the TransparentProxyInterceptor. You can see a few older posts that follow these name changes:
So this is my last post on the Unity Interception Extension until it is released, which I suspect will be fairly soon :)
Below is the updated code from the following example:
Unity Interception Extension and TransparentProxyInterceptor Sample
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 TransparentProxyInterceptor. 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 TransparentProxyInterceptor 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>().SetDefaultInterceptorFor<ISubscriberRepository>(
new TransparentProxyInterceptor());
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 TransparentProxyInterceptor. 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 :)
Conclusion
It is nice to see the core technology of the Policy Injection Application Block being added into Unity v1.2. This allows you to use the Unity Interception Extension without the Policy Injection Application Block, but at the same time giving you the option of pulling in the custom callhandlers and application blocks in Enterprise Library if you want to take advantage of them.
Hope this helps,
David Hayden