混凝土类型与派生接口的注册
本文关键字:注册 接口 派生 类型 混凝土 | 更新日期: 2023-09-27 18:16:56
想知道如何注册这些类型给定他们的继承,等等…
public interface ICommandHandler<in TCommand>
{
void Handle(TCommand command);
}
public abstract class AbstractCommandHandler<T> : ICommandHandler<T>
{
public abstract void Handle(T command);
}
public interface ILoginCommandHandler : ICommandHandler<object>{}
public class LoginCommandHandler : AbstractCommandHandler<object>, ILoginCommandHandler
{
public override void Handle(object command){}
}
目前,我正在做以下事情:
var container = new Container();
container.Register<ICommandHandler<object>, LoginCommandHandler>();
container.Register<ILoginCommandHandler, LoginCommandHandler>();
container.Verify();
var instance = container.GetInstance<ILoginCommandHandler>();
instance.Handle(new object());
这工作,但我想知道这是否是正确的方法。ILoginCommandHandler只是识别命令和减少代码混乱的一种更简单的方法。此外,如果需要的话,我还可以在后面添加特定的其他方法。
而且,我将至少有100个这样的组件,所以我将在每个卫星组件中使用一个包。注册来自多个附属程序集的包的最佳方法是什么?我发现有时候SimpleInjector不喜欢我放置注册的位置(或者我只是做错了)。
我理解您如何尽量减少代码中泛型类型的使用,但是这样做就完全不允许应用泛型修饰。能够在大范围的命令处理程序实现周围轻松地应用装饰器是使用ICommandHandler<T>
抽象的最有力的理由之一。例如,只需使用以下注册:
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(TransactionCommandHandlerDecorator<>));
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(DeadlockRetryCommandHandlerDecorator<>));
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(ValidationCommandHandlerDecorator<>));
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(SecurityCommandHandlerDecorator<>));
然而,如果你想解决一个ILoginCommandHandler
,这意味着所有注册的装饰师需要实现ILoginCommandHandler
。否则,您的容器将永远无法返回这样的装饰器。在您的装饰器上应用一个或两个这样的接口并没有那么糟糕,但是如果您"至少有一百个这样的"接口,这将导致一个不可行的情况。
即使你现在没有任何装饰器,我也不建议这样做,因为拥有这些接口完全不允许在将来添加横切关注点,这将导致更多的代码混乱的情况,就像你目前看到的额外的泛型类型一样。
如果我需要的话,我可以在后面添加其他特定的方法。
你不应该这样做,因为这与这个模式所基于的原则完全冲突。为什么消费者需要更多的方法来执行那个用例?这两个方法是两个不同的用例吗?其中一个方法是查询吗?当你这么做的时候,你会打破五条坚实原则中的三条(如下所述)。它同样不允许应用横切关注点,不要忘记,通过引入数百个接口,您将再次引入复杂性。现在你有了一个非常简单的(一般的)抽象。