使用Ninject初始化具有初始值的字段

时间:2012-12-02 06:59:18

标签: c# ninject

我目前正在尝试使用Ninject设置如何为某些字段设置初始值。

我有这样的事情:

public class SomeClass
{
    private ISomething _something;

    public SomeClass(string someParam)
    {

    }

    public void DoAThing()
    {
        _something.DoSomething();
    }
}

我的困境在于将_something设置为初始值,因为我不希望该类知道要使用哪个ISomething的默认实现,是否有办法在Ninject实现这一目标?

我应该补充说,通过构造函数传递初始值不是一种选择。

我还应该补充一点,这是在一个类库中,因此任何有关如何以及何时设置内核的信息。注射应该很棒:)。

详细说明:似乎人们可能会感到困惑,我不是想让ISomething进入类(它不是依赖),而是ISomething的默认实现是依赖,这是为什么我选择了服务定位器模式,对于实际的依赖关系,我当然会在构造函数中使用它们。

感谢。

2 个答案:

答案 0 :(得分:1)

是的,拥有高度耦合的类并不是很好,因此取决于抽象是一个不错的选择。但是隐藏你的依赖关系不是很好的解决方案。使它们对您的类的客户端可见,并使用依赖注入为您的类提供依赖项的具体实现:

public class SomeClass
{
    private ISomething _something;

    public SomeClass(ISomething something, string someParam)
    {
        _something = something;
    }

    public void DoAThing()
    {
        _something.DoSomething();
    }
} 

还要考虑创建工厂,它将为创建的ISomething个对象提供SomeClass的默认实现。

答案 1 :(得分:0)

最后,我决定使用静态IOC访问类,以允许我的代码访问类库中用于主注入的核心Ninject内核。

所以:

internal static class IOC
{
    private static readonly IKernel _kernel;

    static IOC()
    {
        _kernel = new StandardKernel(new IModule[] {
            new SomethingModule(),
        });
    }

    static T Get<T>()
    {
        return _kernel.Get<T>();
    }
}

internal sealed class SomethingModule : StandardModule
{
    public override void Load()
    {
        Bind<ISomething>().To<ConcreteSomething>(
            new ConstructorParam("arg", "value"));
    }
}

然后在我上一课:

public class SomeClass
{
    private ISomething _something;

    public SomeClass(string someParam)
    {
        _something = IOC.Get<ISomething>();
    }

    public void DoAThing()
    {
        _something.DoSomething();
    }
}

现在我可以得到具体的实现,甚至用默认值初始化它们来启动!

使用默认值初始化具体类的方法有点脆弱,但我确信在Ninject中有更聪明的方法可以实现这一点,但它看起来似乎是服务定位器式代码的混合解决方案Ninject工作得很好!

BTW我相信你也可以在不同的范围内拥有多个IOC容器(它们通过Ninject传递:P),以防止创建一个庞然大物“无所不在”的内核。

希望这有助于某人!