我们可以使用Unity拦截/扩展/自定义代理来执行此操作吗?
// psuedo-code
using (var childContainer = new container.CreateChildContainer())
using (var scope = new TransactionScope())
{
childContainer.Resolve<TMyService>().PerformCall(...);
scope.Complete();
}
目前,上述代码是作为WCF行为实现的。我们现在拥有直接访问此服务层的类,而不是进行WCF调用并需要此行为。有趣的是我们需要在统一拦截中创建一个子容器。
答案 0 :(得分:2)
是。我不明白为什么你不能。但是......
尽管拦截的使用经常放松了对干净SOLID设计的需求,但是当你想要这样做时,你仍然需要一个SOLID设计。
我已经写过关于启用此here的这类设计,以及它归结为您将为您想要包含在设计背后的操作建模,例如{{1}使用ICommandHandler<T>
方法。通过这样的设计,你可以创建一个装饰器(或者在Unity的情况下是一个拦截器),它用一个类来包装一个真正的类,这个类添加了一个像这样的子容器:
Handle(T)
一个装饰器,它添加了这样的事务范围:
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);
}
}
}
通过在两个装饰器中包装实际处理程序,您可以使用此行为扩展处理程序。当然,装饰器是Unity无法处理的概念,但是在使用Unity时可以使用拦截器轻松地重写它,但同样,优秀的设计是你唯一的朋友。
答案 1 :(得分:0)
不,我认为你没办法做到这一点。您可以执行TransactionScope部分,但解析/调用部分我只是看不到工作。
嗯,我想你可以让它发挥作用。您需要一个TMyService的虚拟实例(或任何您正在拦截的对象),并且您的拦截行为需要进行一系列反射来确定要抓取的类型,解析它并再次使用反射来调用特定的方法。它可以做到,但它会非常缓慢。
我不会为此提供代码,因为我认为这不是一个好主意。你想用什么方案来实现它 - 可能有一种更简单的方法来实现它。