我希望 Peter 或 Ruben 看到这个问题,因为他们似乎是关于 Ninject 的人。我需要创建一个自定义提供程序,因为我有一个需要 4 个参数的类。这两个可以被注入(inject),因为它们是类型,但另外两个是配置参数并且是整数。它们指的是以毫秒为单位的超时。
[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;
}
}
我以前依靠我创建的工厂来获取超时和延迟的配置设置,并注入(inject)一些东西和其他东西。现在看来,我必须创建自己的自定义提供程序。我同意。
几点加分:
参数。但这创造了一个
欺骗性的 API。对象应该是
以准备使用状态返回,并且
没有这 4 个论点,它不是
可以使用。
方法注入(inject)。
所以,我最后的问题:
更新:按要求提供代码示例
然后我假设我的提供者会喜欢这样的东西:
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);
}
}
但是因为我现在使用的是提供程序,所以它会绕过 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
}
}
有什么我想念的吗?
最佳答案
你们在这里进行了很好的对话,但我想我会根据原始问题添加一个答案来帮助澄清事情。
简短的回答是,如果您指定 .Using<SingletonBehavior>
,Ninject 仍将确保您拥有一个对象的单个实例。在您的绑定(bind)语句中,无论激活机制如何 - 即您不会绕过 Ninject 的机制,即当使用您自己的提供程序时,您不会绕过 Ninject 确保仅创建一个对象实例的机制 .ToProvider
语法 -- 或 .ToMethod
语法。
你应该简单地编写你的提供者来提供对象实例——没有其他语义被强加给提供者。因此,不需要您在上面的示例中提供的创建单例实例所需的所有典型 goo。
例如,您的提供者变得更加简单;虽然,我添加了解决 ISomething
和 IOther
在原始示例中使用 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 = context.Kernel.Get<ISomething>();
IOther other = context.Kernel.Get<IOther>();
return new MyClass(something, other, timeout, delay );
}
}
Ninject 模块中的绑定(bind)语句如下所示:
public class MyModule : StandardModule {
public override void Load() {
Bind<IMyClass>()
.ToProvider<MyClassProvider>()
.Using<SingletonBehavior>();
}
}
通过使用
SingletonBehavior
即使您使用自己的提供程序,Ninject 仍然只会给您一个 MyClass 实例。这很容易测试。您可以将 DateTime 属性添加到您的类中,将其设置为
DateTime.Now
在构造函数中检查多次调用 Get() 返回的对象——即使您在提供程序中创建了类,它们都将具有相同的时间。接下来,更改 Using<SingletonBehavior>
至Using<TransientBehavior>
并观察差异。您每次都会得到一个新的,全部由您的提供商创建。希望这能有所帮助——顺便说一句,我不确定我是不是你所说的彼得,但如果是这样,我很受宠若惊!
关于.net - 使用 Ninject,如果我创建自定义提供程序,我必须确保单个实例还是可以使用 SingleInstance 属性?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2325069/