使用Ninject,如果我创建自定义提供程序,我必须确保单个实例,还是可以使用SingleInstance属性?

uri*_*ium 6 .net unit-testing dependency-injection ninject

我希望彼得或鲁本看到这个问题,因为他们似乎是关于Ninject的人.我需要创建一个自定义提供程序,因为我有一个需要4个参数的类.可以注入两个,因为它们是类型,但另外两个是配置参数并且是整数.它们以毫秒为单位引用超时.

[SingleInstance]
MyClass
{
    ISomething something;
    IOther other;
    int timeout;
    int delay;

    [Inject]
    MyClass(ISomething something, IOther other, int timeout, int delay)
    {
        this.something = something;
        this.other = other;
        this.timeout = timeout;
        this.delay = delay;
    }
}    
Run Code Online (Sandbox Code Playgroud)

我以前依赖于我创建的工厂来获取超时和延迟的配置设置以及注入其他内容.现在它似乎正确,我将不得不创建自己的自定义提供程序.哪个我没关系.

几点加分:

  1. 我知道我可以在参数上使用注入.但这会产生欺骗性的API.对象应该在准备使用状态下返回,如果没有这4个参数,它就不能使用了.
  2. 相同的参数适用于方法注入.

所以,我最后的问题:

  • 这是否意味着我可以控制再次确保单个实例,还是Ninject仍然会通过[SingleInstance]属性来处理它?
  • 我不应该只是回到我的工厂吗?在这种情况下,使用Ninject可以获得什么?

更新:代码样本按要求

然后,我认为我的提供者想要这样的东西:

class MyClassProvider : SimpleProvider<MyClass> {
protected override MyClass CreateInstance(IContext context) {
    int timeout= ConfigurationManager.AppSettings.Get("timeout");
    int delay= ConfiguraionManager.AppSettings.Get("delay");
    ISomething something = new SomethingImpl();
    IOther other = new OtherImpl();
    MyClass newOne = New MyClass(something, other, timeout, delay);
    }
}
Run Code Online (Sandbox Code Playgroud)

但是因为我现在正在使用提供程序,所以绕过了ninject的机制,确保只创建了一个对象的实例,所以我必须依靠:

class MyClassProvider : SimpleProvider<MyClass> {

    protected static readonly MyClass myClassInstance;
    private static object locker = new object();

    protected override MyClass CreateInstance(IContext context) {
        if (myClassInstance == null) 
        {
            lock (locker)
            {
                int timeout = ConfigurationManager.AppSettings.Get("timeout");
                int delay = ConfiguraionManager.AppSettings.Get("delay ");
                ISomething something = new SomethingImpl();
                IOther other = new OtherImpl();
                MyClass newOne = New MyClass(something, other, timeout, delay );
            }
            return MyClassInstance
        }
        return myClassInstance
    }
}
Run Code Online (Sandbox Code Playgroud)

有什么东西我错过了吗?

Rub*_*ink 1

老实说,我很难理解你的问题 - 也许你如何创建它的代码示例可能会有所帮助(尽管你的问题通常措辞很好)。但这里有一个刺。

不确定你的意思SingleInstance- 它来自哪里?(实际上我在 v1 中没有意识到SingletonAttribute,但看到它不在 2.0 Core 中)。虽然它在某些情况下有意义,但我绝对不会在类上使用行为属性作为默认方法(即,将其放在绑定定义中)。

我仍然会尝试使用 Provider (或Bind<T>.To*使用 lambda 重载作为用更少的代码编写工厂的方法),特别是当实例化行为层可以在其之上使用时,您将采购所有以同样的方式处理对象,这是一件好事。

我提出的另一个建议是,你的裸露超时和延迟参数可能会成为你的 DI 树的一等公民,例如,IConnectivityPolicy可以跨多个类使用的东西。