Policy Injection lifetime & Best Practices questions

Nov 6, 2013 at 4:51 PM
Edited Nov 6, 2013 at 4:52 PM
Hey all,
I have been using Unity for almost 2-3 years now and i never managed to get a really straight answer about this.

Lately i've been using a lot of Interception to leverage crosscutting concerns (Validation, Logic, other business rules) and i have the following questions:

What is the lifetime of a Policy against a singleton object ?
That is, assuming i am resolving a singleton...the policy pipeline against this object is created each time Unity resolves it or just the first time? Im asking this because of the performance implications...

Another question, what are the best practices around the Policy Injection declarations ?
  1. It is preferable to create policies around concerns (like LoggingPolicy, ValidationPolicy) where i target multiple types, methods (...),using MatchingRules ? (Usually a policy definition like this only has one CallHandler...)
  2. Or...is it preferable to create policies around a specific business object (like AccountRepositoryPolicy, UserApiPolicy) where the policy definition (MatchingRule) targets a specific interface and has multiple CallHandlers (Ex: LoggingCallHandler, ValidationCallHandler, (...)) ?
Lastly, which takes the most performance hit ?
  1. Lots of Policies and one or two CallHandlers per policy
  2. Or... Very few Policies but with 4 or 5 callhandlers per policy
Thank you all..
Nov 7, 2013 at 6:33 AM
By default the singleton object is stored in a ContainerControlledLifetimeManager. When the object is resolved the instance is retrieved from the lifetime manager and then interception is applied against the object (e.g. InstanceInterception). The pipeline itself is cached.

If you really want to cache the wrapped object then you could resolve and then overwrite the registration with the wrapped object:
IUnityContainer container = new UnityContainer().LoadConfiguration();

var bankAccount = container.Resolve<IBankAccount>();
// overwrite the registration with the wrapped instance
container.RegisterInstance<IBankAccount>(bankAccount);

// Unity will short circuit on pre-buildup (because the value is held in a lifetime manager) 
// and post-buildup (because the type is IInterceptingProxy)
bankAccount = container.Resolve<IBankAccount>();

One thing I'm wondering is if this approach is thread-safe.

In terms of policy declaration best practices, the first option seems more familiar to me but it could depend on your exact needs. I'm not aware of any explicit recommendations.

And if you are concerned about performance it would be best to measure. The number of possible methods to intercept would be a factor to. If the overall number of CallHandlers is equal in both cases then I would guess less policies would be faster.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Nov 7, 2013 at 2:41 PM
Thank you very much for your answer!

Just one more question, if we have 2 policies that target the same types but with different callHandlers, how is the pipeline built against the object?
From what i've read, there is only one pipeline, no matter how many policies exist against it..how does Unity determine the execution order of the policies? Only CallHandlers have an assignable Order property..
Nov 10, 2013 at 9:25 PM
Policies are executed in the order they are defined. Actually, an AttributeDrivenPolicy is first so that CallHandlerAttributes "just work". After that, RuleDrivenPolicy's are executed in the order they are defined.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Nov 13, 2013 at 4:46 PM
randylevy wrote:
Policies are executed in the order they are defined. Actually, an AttributeDrivenPolicy is first so that CallHandlerAttributes "just work". After that, RuleDrivenPolicy's are executed in the order they are defined.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Thank you very much for your answer. Although i did not quite understood what would be the actual execution order of the callhandlers.

That said, i've tested it myself, and i can confirm that Unity honors the CallHandler execution order, regardless of the Policy definition order.

The following configuration:
<policy name="MyFirstPolicy">
  <matchingRule name="MatchMyType" type="TypeMatchingRule">
    <constructor>
      <param name="typeName" value="IMyType" />
    </constructor>
  </matchingRule>
  <callHandler name="ValidationHandler" type="ValidationHandler">
    <property name="Order" value="20" />
  </callHandler>
</policy>
<policy name="MySecondPolicy">
  <matchingRule name="MatchMyType" type="TypeMatchingRule">
    <constructor>
      <param name="typeName" value="IMyType" />
    </constructor>
  </matchingRule>
  <callHandler name="LoggingHandler" type="LoggingHandler">
    <lifetime type="singleton" />
    <property name="Order" value="10" />
  </callHandler>
</policy>
The execution order is:
  1. LoggingHandler
  2. ValidationHandler
Nov 14, 2013 at 12:48 AM
Sorry about that answer -- I guess I misunderstood what you wanted to know. Unity loops through all the policies in the order they occur and adds the specific handlers. The handler list is effectively sorted by Order. After the ordered CallHandlers are added, "unordered" (i.e. Order = 0) CallHandlers are then added in the order they occur.

The above logic can result in unexpected behavior. For example, if you have 3 call handlers with Orders of 10, 0 , -10 then the order of execution will be -10, 10, 0 and not -10, 0, 10 as you might expect.

~~
Randy Levy
entlib.support@live.com
Enterprise Library support engineer
Support How-to
Marked as answer by calexandre on 11/20/2013 at 2:29 PM