unity-containerioc-containerunity-interception

Unity Container: create child container around every method call


Can we use Unity interception/extensions/custom proxy to perform this?

// psuedo-code
using (var childContainer = new container.CreateChildContainer())
using (var scope = new TransactionScope())
{
  childContainer.Resolve<TMyService>().PerformCall(...);
  scope.Complete();
}

Currently the above code is implemented as a WCF behaviour. We now have classes that access this service layer directly rather then making WCF calls and need this behaviour. The interesting part is we need to create a child container inside the unity interception.


Solution

  • Yes. I don't see why you couldn't. However...

    although the use of interception often loosens the need to have a clean and SOLID design, when you want to do this, you still need a SOLID design.

    I've written about these kind of designs that enable this here, and what it comes down to is that you will have model the operations you want to wrap behind a design, such as an ICommandHandler<T> with a Handle(T) method. With such a design, you can create a decorator (or in Unity's case an interceptor) that wraps a real class with a class that adds a child container like this:

    public class ChildContainerCommandHandlerDecorator<T>
        : ICommandHandler<T>
    {
        private readonly ICommandHandler<T> decorated;
        private readonly Container container;
    
        public ChildContainerCommandHandlerDecorator(
            ICommandHandler<T> decorated, Container container)
        {
            this.decorated = decorated;
            this.container = container;
        }
    
        public void Handle(T command)
        {
            using (container.CreateChildContainer())
            {
                this.decorated.Handle(command);
            }
        }
    }
    

    And a decorator that adds a transaction scope like this:

    public class TransactionCommandHandlerDecorator<T>
        : ICommandHandler<T>
    {
        private readonly ICommandHandler<T> decorated;
    
        public TransactionCommandHandlerDecorator(
            ICommandHandler<T> decorated)
        {
            this.decorated = decorated;
        }
    
        public void Handle(T command)
        {
            using (var scope = new TransactionScope())
            {
                this.decorated.Handle(command);
    
                scope.Complete();
            }
        }
    }
    

    By wrapping real handlers in both decorators, you can extend handlers with this behavior. Of course, decorators is a concept that Unity is unable to handle, but you can easily rewrite this using interceptors when working with Unity, but again, good design is your only friend here.