如何在Ninject中使用Provider

8

我有以下代码

public class Something {
    [Inject]
    public Configuration config {get;set;} //singleton
    [Inject]
    public Provider<WindowHandler> windowsProvider { get; set; } //NOT singleton

    public void Search(string text) {
        WindowHandler handler = windowsProvider.Create(xxxxxx);
        //use the new handler that was created
    }
}

但是看起来 Provider 接受一个 IContext,而我放置 xxxxxx。难道不应该使用我从内核引导和创建 Something.cs 时的 IContext 吗?Provider 上没有无参数 Create 方法吗?(我来自 Guice 领域的角度,它会像上面的代码一样编码)。

所以问题是我如何正确地做到这一点?

谢谢, 迪恩

2个回答

12

看起来你在尝试在代码中将提供程序用作工厂。

Ninject术语中的提供程序是一个由Ninject提供的工厂,用于创建特殊创建的对象。因此,它获得解析上下文,该上下文可用于创建不同的实例,具体取决于实例注入到哪里。

public class FooProvider : Provider<IFoo>
{
    public override IFoo CreateInstance(IContext ctx)
    {
        // add here your special IFoo creation code
        return new Foo();
    }
}

kernel.Bind<IFoo>().ToProvider<FooProvider>();

你想要的是在你的代码中创建WindowHandler实例的工厂。因此,创建一个接口来创建实例,如下所示:

public interface IWindowHandlerFactory
{
    WindowHandler Create();
}

Bind<IWindowHandlerFactory>().ToFactory();

你也可以注入 Func<WindowHandler> 而无需添加配置。但是在我看来这意义不大。

注意:所有这些都需要 Ninject.Extensions.Factory,可从Nuget预发布3.0.0-rc2中获取。

另请参阅:http://www.planetgeek.ch/2011/12/31/ninject-extensions-factory-introduction/


Func<WindowHandler> 正是我正在寻找的。我们所使用的版本是 2.0,难道没有其他方法可以实现吗? - Dean Hiller
1
请参见https://dev59.com/QW445IYBdhLWcg3wdqSO#4851885。 - Remo Gloor

1

好的,我的最终解决方案是在Ninject 2.0中使用以下代码来欺骗系统...

        var windowFactory = kernel.Get<IEWindowFactory>();
        var tabFactory = kernel.Get<IETabFactory>();
        windowFactory.Kernel = kernel;
        tabFactory.Kernel = kernel;

而在绑定列表中,我有

Bind<IEWindowFactory>().ToSelf().InSingletonScope();
Bind<IETabFactory>().ToSelf().InSingletonScope();

然后我只需启动我的应用程序

var main = kernel.Get<MainForm>();
main.Start();

当然,这些工厂是在 MainForm 的层次结构中我需要它们的地方被注入的。
因此,我手动在启动时放置内核,然后当我引导我的应用程序时,这些工厂自然成为带有 [Ninject] 注释的类中的字段,因此它们可以创建对象。虽然不太干净,但在我们获得 3.0 版本之前,它能够工作(尽管我讨厌我必须为其编写额外的工厂类的代码)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接