使用Ninject,我有一个接口,我想绑定到具体实现的单个实例。例如:
public interface IFoo { //... }
public class Foo { //... }
现在通常,我会像这样绑定类似的东西:
kernel.Bind<IFoo>().To<Foo>().InSingletonScope();
但是,我需要为Foo
的构造函数添加参数。通常,再次,这不会是一个太大的问题(我认为):
kernel.Bind<IFoo>()
.To<Foo>()
.InSingletonScope()
.WithConstructorArgument("bar", myBar);
现在问题是我在设置所有绑定时无法知道myBar
的值。我需要推迟到第一次需要IFoo
时(注意,实际上我有几个参数要通过)。所以我需要的是一个单例,它在初次使用时会被初始化,只能在那时获得参数。
最好的方法是什么?我假设有Factory的东西可能是解决方案,但我没有看到正确的方法来做到这一点。我不想每次都创建一个 new Foo
。
答案 0 :(得分:1)
正如我上面的评论。真正的问题是,当你需要Foo时,你可能没有构造参数。在这种模式中,您可以根据需要绑定所有接口,并在准备好时调用IInitialiser.Initialise(显示您需要保留引用或使其保持静态)。
如果在正确设置之前调用它,Foo将抛出异常
IFoo保持不变
可以调整IInitialiser实现以轮询数据库或响应事件或任何适合您最近配置的最佳配置
using System;
namespace UnitTestProject3
{
public interface IFoo
{
int GetAllTheFoo();
}
public interface IInitialiser
{
void Initialise(int x);
int GetX();
bool IsReady { get; }
}
public class Foo : IFoo
{
private bool isInitalised;
private int x;
private IInitialiser i;
public Foo(IInitialiser i)
{
this.isInitalised = false;
this.i = i;
}
protected void Init()
{
if (this.isInitalised)
{
return;
}
else if (i.IsReady)
{
x = i.GetX();
this.isInitalised = true;
return;
}
else
{
throw new Exception("you have not set x");
}
}
public int GetAllTheFoo()
{
Init();
return x;
}
}
}
答案 1 :(得分:1)
您可以使用Factory扩展名。
public interface IFooFactory
{
IFoo CreateFoo(string bar);
IFoo CreateFoo();
}
public interface IFoo
{
string Bar { get; set; }
}
public class Foo : IFoo
{
public string Bar { get; set; }
public Foo(string bar)
{
Bar = bar;
}
}
kernel.Bind<IFoo>().To<Foo>().InSingletonScope();
kernel.Bind<IFooFactory>().ToFactory();
IFoo foo1 = fooFactory.CreateFoo("myBar");
IFoo foo2 = fooFactory.CreateFoo("myDifferentBar"); // value is basically ignored here
IFoo foo3 = fooFactory.CreateFoo();
这将始终返回相同的Foo实例。当然,如果你首先调用paremeterless方法,它将导致异常。
答案 2 :(得分:0)
鉴于其他两个答案,我可能完全忽略了问题的重点,但为什么不会像你这样简单的工作:
kernel.Bind<IFoo>().ToMethod(x => CreateFoo()).InSingletonScope();
CreateFoo
将负责使用您需要的任何参数集构建单个对象。在调用CreateFoo
时,您应该已经知道参数是什么。