如何使用具有Dependecy Injection的工厂而不使用Service Locator模式

Mer*_*ham 3 .net dependency-injection ninject factory-pattern

我有一个GUI应用程序.在其中,我允许用户从容器提供的算法列表中进行选择.每个算法将在另一个视图中作为后台任务启动.我需要支持此视图的多个实例,并支持同一算法的多个实例.该视图也将由容器提供.该算法也是有状态的.

所以我有一个案例,我需要创建我的视图和算法的实例,并在运行时将它们绑定在一起.我没有这些实例的静态绑定点,所以我不能使用正常的注入工具(构造函数或属性注入).我不想打电话new,我不想像服务定位器那样使用容器.

我在Castle.Windsor中使用Typed Factory Facility解决了这个问题,但我不得不在我的应用程序中处理工厂.工厂设计也有点奇怪,因为当我完成它们时,我不得不将我的实例返回工厂.

我现在正在研究使用NInject,因为到目前为止,学习曲线和介绍文档要好得多,我想为我的团队提出一个容器供我使用.但是对于这样的场景,我认为我必须编写自己的工厂并直接调用内核来解析新实例(嵌入在工厂中的Service Locator),以及在我的注册码中添加工厂方法.

是否有一种通用的方法来解决这个问题,或者这只是一个依赖注入本身不能解决的问题?


澄清:

我在评论中说我想要一个Ninject的具体答案,我已经得到了.非常感谢:)在现实生活中,我可能只是使用已经提出的实用解决方案.

但是我把我的基础作为一个具体的问题来解决我的问题.我希望在标题中对这个问题有一个更纯粹的基本答案.

是否有纯DI技术允许用户在运行时触发组件的新实例?或者所有这些实现都将容器用作服务定位器,或者需要对容器的特定"怪癖"(例如内置工厂支持,ala Castle.Windsor或即将发布的Ninject工厂特性),而不是而只利用"纯"DI的方方面面?

我只听说过Java世界中的这个词,我对它的含义并不太了解 - 请原谅我:)我正在寻找某种"注射"吗?

Rem*_*oor 8

最好你创建这样的工厂界面

public interface IFooFactory
{
    IFoo CreateFoo(int someParameter);
}
Run Code Online (Sandbox Code Playgroud)

对于Ninject 2.3,请参阅https://github.com/ninject/ninject.extensions.factory,并通过添加以下配置由Ninject实现.

Bind<IFooFactory>().AsFactory();
Run Code Online (Sandbox Code Playgroud)

对于2.2自己实现.此实现是容器配置的一部分,而不是您的实现的一部分.

public class FooFactory: IFooFactory
{
    private IKernel kernel;
    public FooFactory(IKernel kernel)
    {
        this.kernel = kernel;
    }

    public ISession CreateFoo(int someParameter)
    {
        return this.kernel.Get<IFoo>(
            new ConstructorArgument("someParameter", someParameter));
    }
}
Run Code Online (Sandbox Code Playgroud)