Reuse of policies

Oct 22, 2008 at 4:17 PM
I noticed that the interception class has a AddPolicy method given a name. This will always create a new policy. In which way can we reuse a policy? It would be nice to have a AddPolicy method where you can pass for example a RuleDrivenPolicy. For example I have the following:

 IUnityContainer container = new UnityContainer()
.RegisterInstance<ICallHandler>("DirtyHandler", new DirtyHandler());

container.Configure<Interception>().SetInterceptorFor<Customer>(new VirtualMethodInterceptor())
    .AddMatchingRule(new PropertyMatchingRule("*", PropertyMatchingOption.Set))
    .AddMatchingRule(new CustomAttributeMatchingRule(typeof(DirtyAttribute), true))

If I want the same interception mechanism for an Order object instead of a Customer object, I need to write identically the same statements.
Maybe it would be nice to write something like this

 var dirtyPolicy = new RuleDrivenPolicy(
                new IMatchingRule[]
                    new PropertyMatchingRule("*", PropertyMatchingOption.Set),
                    new CustomAttributeMatchingRule(typeof(DirtyAttribute), true)
                new string[] { "DirtyHandler" });

container.Configure<Interception>().SetInterceptorFor<Customer>(new VirtualMethodInterceptor()).AddPolicy(dirtyPolicy);
container.Configure<Interception>().SetInterceptorFor<Order>(new VirtualMethodInterceptor()).AddPolicy(dirtyPolicy);
Oct 22, 2008 at 6:06 PM
In the case you describe, you don't need a new interception policy at all. Your matching rules match all properties with a setter that have your DirtyAttribute on them, regardless of type. So they'll match Order, and Customer, and Shipper, and anything.

You do need to specify the interceptors for the types separately, but not the policies.


Oct 22, 2008 at 6:36 PM

How can you denote to Unity that it should intercept for a set of classes (Order, Customer, Shipper, etc) ?
There is no documentation yet, but the only way I can see how you can denote to Unity that a particular type should be intercepted is by using the SetInterceptorFor and the SetInterceptorFor expect a type.
From the example, the policy 'DirtyPolicy' is only applied to a Customer type object.

Note that the following intercepts for a Customer and Order, but how to do it globally or by a given criteria?

    .SetInterceptorFor<Customer>(new VirtualMethodInterceptor())
    .SetInterceptorFor<Order>(new VirtualMethodInterceptor())

    .AddMatchingRule(new PropertyMatchingRule("*", PropertyMatchingOption.Set))
    .AddMatchingRule(new CustomAttributeMatchingRule(typeof(DirtyAttribute), true))

Oct 23, 2008 at 12:18 AM
Basically, you don't. At least not automatically.

There's two reasons we don't automatically do this. First, interception is expensive. We've made it a lot faster, but it's still expensive, to the point that we don't want people accidentally turning it on on everything.

Second, there's some limitations within ObjectBuilder that makes it much easier to look up by a single type rather than compare "does this type match some criteria"?

Third (ok, three reasons), we'd need to design another matching rule type language to apply interceptors to types, which was more work than we wanted to do.

In the end, there's definately room for a more automated way to specify the interceptors, but for the above reasons we decided not to do it for this version. Please feel free to experiment (possibly write a Unity extension to implement what you want) and let us know.