温莎,在课堂上注射容器

时间:2013-01-31 09:41:48

标签: castle-windsor

您好在Castle Windsor注册了以下组件:

public class CommandDispatcher : IServiceCommandDispatcher
{
    private readonly IWindsorContainer container;

    public CommandDispatcher(IWindsorContainer container)
    {
        this.container = container;
    }

    #region IServiceCommandDispatcher Members

    public void Dispatch<TCommand>(TCommand command) where TCommand : IServiceCommand
    {
        var handler = container.Resolve<IServiceCommandHandler<TCommand>>();
        handler.Handle(command);
    }

    #endregion
}

调度员的注册方式如下:

Component
   .For<IServiceCommandDispatcher>()
   .ImplementedBy<CommandDispatcher>(),

但是当我解析调度程序的实例时,字段容器为null。 如何将容器传递给已解决的子项?

2 个答案:

答案 0 :(得分:2)

Windsor使用Typed Factory Facility解决了这个问题。

在下面的示例中,我希望实现ICommandHandlerFactory以从我的windsor容器中解析我的命令处理程序。

class CommandDispatcher : IServiceCommandDispatcher
{
    private readonly ICommandHandlerFactory factory;

    public CommandDispatcher(ICommandHandlerFactory factory)
    {
        this.factory = factory;
    }

    public void Dispatch<T>(T command) where T : IServiceCommand
    {
        var handler = this.factory.Create(command);
        handler.Handle(command);
        this.factory.Destroy(handler);
    }
}

为实现这一点,我只需要创建ICommandHandlerFactory接口。

public interface ICommandHandlerFactory
{
    Handles<T> Create<T>(T command) where T : IServiceCommand;
    void Destroy(object handler);
}

由于Windsor将创建实施,因此不需要ICommandHandlerFactory的实施。 Windsor使用以下约定:返回对象的方法是resolve方法,返回void的方法是release方法。

要注册工厂,您需要包含using Castle.Facilities.TypedFactory,然后按如下方式注册您的工厂

container.AddFacility<TypedFactoryFacility>();

container.Register(
     Component.For<ICommandHandlerFactory>()
         .AsFactory()
);

重申您不必为您的工厂编写任何实施代码

答案 1 :(得分:0)

这有效:

container.Register(Component.For<IWindsorContainer>().Instance(container));

它并不理想,因为您仍然需要调用 Resolve 方法。使用工厂可能有更好的方法来做到这一点。这看起来类似于您尝试做的事情:

http://kozmic.net/2010/03/11/advanced-castle-windsor-ndash-generic-typed-factories-auto-release-and-more/