2

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

我有这样的事情:

public class SomeClass
{
    private ISomething _something;

    public SomeClass(string someParam)
    {

    }

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

我的困境来自于_something初始值的设置,因为我不希望类知道ISomething要使用哪个默认实现,有没有办法在 Ninject 中实现这一点?

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

我还应该补充一点,这是在一个类库中,所以任何关于如何以及何时设置内核和注入的信息都会很棒:)

详细说明:似乎人们可能会感到困惑,我不是想将 ISomething 放入类中(它不是依赖项),而是 ISomething 的默认实现是依赖项,这就是我选择服务的原因-locator 模式,对于实际的依赖关系,我当然会将它们放在构造函数中。

谢谢。

4

2 回答 2

1

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

public class SomeClass
{
    private ISomething _something;

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

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

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

于 2012-12-02T22:48:52.163 回答
0

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

所以:

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 的混合解决方案工作得很好好!

顺便说一句,我相信您还可以在不同的范围内拥有多个 IOC 容器(它们自己通过 Ninject 传递:P)以防止创建庞然大物“无处不在”的内核。

希望这对某人有所帮助!

于 2012-12-02T22:39:43.270 回答