我正在与IoC合作,更准确地说是与windsor一起工作,我对一件事情有点怀疑。 现在我正在实现DDD命令层,所以对于每个命令,我都有一个具体的类,如下所示
public class CreateUserCommand : IDomainCommand{
/// implementation
}
每个命令都有一个或多个处理程序,具有以下实现
public class CreateUserHandler : IDomainCommandHandler<CreateUserCommand>
{
public void Handle(CreateUserCommand command)
{
/// implementation
}
}
我的Command Dispatcher出现问题。我目前正在使用以下表格
public class CommandDispatcher : ICommandDispatcher
{
private IWindsorContainer container;
public CommandDispatcher(IWindsorContainer container)
{
this.container = container;
}
public void Dispatch<T>(T command)
{
var commandHandler = container.Resolve<ICommandHandler<T>>();
commandHandler.Handle(command);
}
}
我不喜欢的是调度员关于IoC容器的意识,但同样地,我不知道如何在我需要它时解决处理程序。 Shell我在Dispatcher中注入一个处理程序工厂,并在运行时使用它来解析我的处理程序?
答案 0 :(得分:7)
我使用typed factory facility创建工厂来替换容器使用情况。从概念上讲,这个想法是一样的,但它消除了对容器的依赖。
工厂(没有实施,设施负责):
public interface ICommandHandlerFactory
{
ICommandHandler<T> Create<T>();
}
注册:
// requires Castle.Facilities.TypedFactory namespace
windsorContainer.AddFacility<TypedFactoryFacility>();
// AsFactory() is an extension method in the same namespace
windsorContainer.Register(Component.For<ICommandHandlerFactory>().AsFactory());
然后在你的课堂上:
public class CommandDispatcher : ICommandDispatcher
{
private ICommandHandlerFactory commandHandlerFactory;
public CommandDispatcher(ICommandHandlerFactory commandHandlerFactory)
{
this.commandHandlerFactory = commandHandlerFactory;
}
public void Dispatch<T>(T command)
{
var commandHandler = commandHandlerFactory.Create<T>();
commandHandler.Handle(command);
}
}
答案 1 :(得分:2)
您的composition root中的基础架构代码可以依赖容器,这是可以的。这不是Service Locator anti-pattern的实现,因为服务定位器约为role and not mechanics。
换句话说,只要您的CommandDispatcher
是组合根的一部分(并且只包含基础结构,没有业务逻辑),就可以让它依赖于容器。