IoC避免注入容器

时间:2014-09-15 12:53:06

标签: inversion-of-control castle-windsor command-pattern

我正在与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中注入一个处理程序工厂,并在运行时使用它来解析我的处理程序?

2 个答案:

答案 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是组合根的一部分(并且只包含基础结构,没有业务逻辑),就可以让它依赖于容器。