2

我们可以使用 Unity 拦截/扩展/自定义代理来执行此操作吗?

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

目前,上述代码是作为 WCF 行为实现的。我们现在有直接访问此服务层的类,而不是进行 WCF 调用并需要此行为。有趣的部分是我们需要在统一拦截中创建一个子容器。

4

2 回答 2

2

是的。我不明白你为什么不能。然而...

尽管使用拦截通常会放松对干净和SOLID设计的需求,但是当你想要这样做时,你仍然需要一个 SOLID 设计。

我已经在此处写过有关启用此功能的此类设计,归根结底是您将对要包装在设计后面的操作进行建模,例如ICommandHandler<T>使用Handle(T)方法。通过这样的设计,您可以创建一个装饰器(或者在 Unity 的情况下是一个拦截器),它使用一个添加子容器的类来包装一个真实的类,如下所示:

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);
        }
    }
}

还有一个装饰器,它添加了这样的事务范围:

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();
        }
    }
}

通过在两个装饰器中包装真正的处理程序,您可以使用这种行为扩展处理程序。当然,装饰器是 Unity 无法处理的概念,但是在使用 Unity 时,您可以使用拦截器轻松地重写它,但同样,好的设计是您唯一的朋友。

于 2012-11-04T21:11:07.533 回答
0

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.

于 2012-11-04T18:53:46.773 回答