如何在 Ninject 中使用 Provider

发布于 2024-12-24 18:38:30 字数 590 浏览 0 评论 0原文

我有以下代码

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 似乎在我放置 xxxxxx 的地方采用了 IContext。不应该使用我从内核引导并创建 Something.cs 时的 IContext 吗? Provider 上的无参数 Create 方法在哪里??? (我来自 Guice land 的观点,它的编码方式与上面类似)。

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

谢谢, 院长

I have the following code

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
    }
}

but it seems the Provider takes an IContext where I put xxxxxx. Shouldn't the IContext from when I bootstrapped and created Something.cs from the kernel be used. Where is the no parameter Create method on the Provider??? (I am coming from Guice land point of view where it would be coded like above).

so the question is How do I do this correctly?

thanks,
Dean

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

来日方长 2024-12-31 18:38:30

您似乎正在尝试在代码中使用提供程序作为工厂。

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 而不添加配置。但这在我看来意义不大。

注意:所有这些都需要 Ninject.Extensions.Factory 作为 Nuget 的预发行版 3.0.0-rc2 提供。

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

It seems you are trying to use a provider as a factory in your code.

A provider in Ninject terms is a factory that is given to Ninject to create specially created objects. Therefore it gets the resolving context which can be used to create different instances depending where the instance in injected into.

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>();

What you want is a factory in your coder that creates an instance of WindowHandler. Therefore create an interface to create the instance like this:

public interface IWindowHandlerFactory
{
    WindowHandler Create();
}

Bind<IWindowHandlerFactory>().ToFactory();

Alternatively you can inject Func<WindowHandler> without adding a configuration. But this is less meaningful in my opinion.

NOTE: All this requires Ninject.Extensions.Factory available as prerelease 3.0.0-rc2 from Nuget.

See also: http://www.planetgeek.ch/2011/12/31/ninject-extensions-factory-introduction/

鸠魁 2024-12-31 18:38:30

好吧,我的最终解决方案是使用以下代码在 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 之前,它不是最干净的,但它可以工作(我讨厌我必须为其编写代码的额外工厂类,但是哦,好吧)。

Well, my final solution was to cheat in ninject 2.0 with the following code...

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

and in the bindings list I have

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

and after that I just start my app

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

and of course the factories are injected where I need them in the heirarchy of that MainForm.

so I manually put the kernel when starting up and then when I bootstrap my app, naturally these factories are fields in classes with [Ninject] annotation and so they can create objects. not the cleanest until we get 3.0, but it works(and I hate the extra factory classes I have to write code for but oh well).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文