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.

有帮助吗?

解决方案

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.

其他提示

No, I don't see a way you could do this. You could do the TransactionScope part, but the resolve/call part I just don't see working.

Well, I guess you could get it to work. You'd need a dummy instance of TMyService (or whatever object you're intercepting), and your interception behavior would need to do a bunch of reflection to figure out the type to grab, resolve it, and use reflection again to invoke the specific method. It could be done, but it would be hideously slow.

I'm not going to provide code for this, because I don't think it's a good idea. What scenario are you trying to implement with this - there's probably an easier way to accomplish it.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top