C# 温莎通用装饰器

C# 温莎通用装饰器,c#,generics,castle-windsor,ioc-container,C#,Generics,Castle Windsor,Ioc Container,我试图在几个非通用命令处理程序周围找到一个通用的装饰程序。在不单独注册每个命令处理程序的情况下,这是可能的吗 当前温莎命令处理程序注册(有效): container.Register(Classes.fromsassemblyNamed(namespaceName) .BasedOn(typeof(IDomainCommandHandler)) .WithService.AllInterfaces() .生活方式(暂时的); 简单装饰器: public class Decorator<T

我试图在几个非通用命令处理程序周围找到一个通用的装饰程序。在不单独注册每个命令处理程序的情况下,这是可能的吗

当前温莎命令处理程序注册(有效):

container.Register(Classes.fromsassemblyNamed(namespaceName)
.BasedOn(typeof(IDomainCommandHandler))
.WithService.AllInterfaces()
.生活方式(暂时的);
简单装饰器:

public class Decorator<T> : IDomainCommandHandler<T> where T : IDomainCommand
{
    private readonly IDomainCommandHandler<T> _decoratedCommandHandler;

    public Decorator(IDomainCommandHandler<T> decoratedCommandHandler)
    {
        _decoratedCommandHandler = decoratedCommandHandler;
    }

    public void Handle(T command)
    {
        _decoratedCommandHandler.Handle(command);
    }
}
公共类修饰符:IDomainCommandHandler,其中T:IDomainCommand
{
私有只读IDomainCommandHandler _decoratedCommandHandler;
公共装饰器(IDomainCommandHandler装饰的CommandHandler)
{
_decoratedCommandHandler=decoratedCommandHandler;
}
公共无效句柄(T命令)
{
_decoratedCommandHandler.Handle(命令);
}
}
简单命令/处理程序:

public class MyCommand : IDomainCommand
{

}

public class MyCommandHandler : IDomainCommandHandler<MyCommand>
{
    public void Handle(MyCommand command)
    {
    }
}
公共类MyCommand:IDOMAIN命令
{
}
公共类MyCommandHandler:IDomainCommandHandler
{
公共无效句柄(MyCommand命令)
{
}
}
我尝试了以下注册,但没有申请装饰师

container.Register(Component.For(typeof(IDomainCommandHandler<>))
    .ImplementedBy(typeof(Decorator<>))
    .LifestyleTransient());
container.Register(Component.For(typeof(IDomainCommandHandler))
.实施人(类型(装饰人))
.生活方式(暂时的);
建议

编辑: 我最初忘记提到的另一个限制是,其中一些命令处理程序由两个不同的应用程序使用。一个需要修饰符,另一个不需要。

您可能会得到“在尝试解析组件时检测到依赖循环…”,对吗?这是因为decorator的ctor包含IDomainCommandHandler

//MyCommand type could be provided through a TypeFactoryComponentSelector     
var myDecoratedCommandHandler = container.Resolve<IDomainCommandHandler<MyCommand>>();
公共装饰器(IDomainCommandHandler装饰的CommandHandler)
当你试图在装饰器内解决IDomainCommandHandler时,它就爆炸了

此处的解析链如下所示:

  • 给我一个命令处理程序

    //MyCommand type could be provided through a TypeFactoryComponentSelector     
    var myDecoratedCommandHandler = container.Resolve<IDomainCommandHandler<MyCommand>>();
    
    //可以通过TypeFactoryComponentSelector提供MyCommand类型
    var myDecoratedCommandHandler=container.Resolve();
    
  • Castle解析了Decorator,但随后又解析了自己的依赖关系

    IDomainCommandHandler<T> decoratedCommandHandler
    
    IDomainCommandHandler修饰的CommandHandler
    
  • 因为你们已经提供了T,在本例中是MyCommand,Castle再次去解析Decorator,当它做了两次时,它就放弃了。IDomainCommandHandler的唯一注册是Decorator。讨论了这类问题

    您可以通过使用来获得类似“装饰者”的属性

    当您想要扩展一个实现时,通常会应用decorator模式。是这样吗?你能举一个可能扩充你的DomainCommandHandler的例子吗?您是否正在尝试实施交叉关注点


    坚持您的风格的唯一可能的答案是使用ITypedFactoryComponentSelector或FactoryMethod实现,并使用分辨率堆栈。然后可以递归遍历容器的解析堆栈,如果堆栈中有Decorator,则返回MyDomainCommandler。这看起来像是解析链的一个钩子,上面写着“现在我看到您已经在解析Decorators依赖项,所以请不要再次解析Decorator。”

    您是否得到“在尝试解析组件时检测到依赖项循环…”我没有收到任何错误。decorator根本不适用。@agartee如何解析命令处理程序?我们使用的是与Udi Dahan的域事件处理器非常相似的东西:“您能举个例子吗?”。那么,您如何看待添加:基于权限的安全性、基于行的安全性、字段验证、业务规则验证、审计跟踪、事务处理、死锁重试、分析。。我需要继续吗?在我编写的应用程序中,我通常将这些横切关注点中的大多数应用到我的命令处理程序中。所有这些都是实际和真实的需求,但在一个地方将它们实现为域服务/命令的装饰器看起来像是过度使用了该模式。只是我的意见。你看过[Sharp Architecture](docs.sharparchitecture.net/en/latest/)了吗?他们有好主意。您甚至可以查看MVC管道—管道中有用于Autho&Authe、模型验证、模型绑定的单独位置。。。等等,你试过动态代理吗?我发现它很适合交叉关注点。我会看一看,但现在我的需求很简单。直奔波斯夏普似乎有些极端。Windsor拦截器可能更有意义,如果通过属性设置它们,我不应该有注册问题,但现在我必须更新所有命令,并且在定义新命令时还要记住一件事。拦截器和PostSharp实现本质上是装饰器。我发现了另一个问题,答案建议在这里使用ISubDependencyResolver:
    IDomainCommandHandler<T> decoratedCommandHandler