我是 ninject 的新手
我一直在拆开别人的代码,发现了几个 nInject 模块的实例——派生自 Ninject.Modules.Module 的类,并且有一个包含大部分代码的加载方法。
通过调用 StandardKernel 实例的 LoadModule 方法并将模块类的实例传递给它来调用这些类。
也许我在这里遗漏了一些明显的东西,但是与仅仅创建一个普通的旧类并调用它的方法或可能是一个带有静态方法的静态类相比,这样做有什么好处?
我是 ninject 的新手
我一直在拆开别人的代码,发现了几个 nInject 模块的实例——派生自 Ninject.Modules.Module 的类,并且有一个包含大部分代码的加载方法。
通过调用 StandardKernel 实例的 LoadModule 方法并将模块类的实例传递给它来调用这些类。
也许我在这里遗漏了一些明显的东西,但是与仅仅创建一个普通的旧类并调用它的方法或可能是一个带有静态方法的静态类相比,这样做有什么好处?
Ninject 模块是用于向 IoC 容器注册各种类型的工具。优点是这些模块然后保存在它们自己的类中。这允许您将不同的层/服务放在它们自己的模块中。
// some method early in your app's life cycle
public Kernel BuildKernel()
{
var modules = new INinjectModule[]
{
new LinqToSqlDataContextModule(), // just my L2S binding
new WebModule(),
new EventRegistrationModule()
};
return new StandardKernel(modules);
}
// in LinqToSqlDataContextModule.cs
public class LinqToSqlDataContextModule : NinjectModule
{
public override void Load()
{
Bind<IRepository>().To<LinqToSqlRepository>();
}
}
拥有多个模块允许关注点分离,即使在您的 IoC 容器中也是如此。
你们其他人的问题听起来更像是关于 IoC 和 DI 作为一个整体,而不仅仅是 Ninject。是的,您可以使用静态配置对象来完成 IoC 容器所做的几乎所有事情。当您有多个依赖关系层次结构时,IoC 容器变得非常好。
public interface IInterfaceA {}
public interface IInterfaceB {}
public interface IInterfaceC {}
public class ClassA : IInterfaceA {}
public class ClassB : IInterfaceB
{
public ClassB(IInterfaceA a){}
}
public class ClassC : IInterfaceC
{
public ClassC(IInterfaceB b){}
}
在这一点上,构建 ClassC 是一件痛苦的事,具有多种深度的接口。向内核询问 IInterfaceC 要容易得多。
var newc = ApplicationScope.Kernel.Get<IInterfaceC>();
也许我在这里遗漏了一些明显的东西,但是与创建一个普通的旧类并调用它的方法相比,或者可能是一个带有静态方法的静态类有什么好处?
是的,您可以只调用一堆Bind<X>().To<Z>()
语句来设置绑定,而无需模块。
不同之处在于,如果您将这些语句放在一个模块中,那么:
IKernel.Load(IEnumerable<Assembly>)
可以通过反射动态发现这些模块并加载它们。IKernel.Unload(string)
也许我在这里遗漏了一些明显的东西,但是与仅仅创建一个普通的旧类并调用它的方法或可能是一个带有静态方法的静态类相比,这样做有什么好处?
对我们来说,这是在以后很容易添加测试的能力。只需用模拟对象覆盖一些绑定,瞧……在没有将“一切”连接起来的 DI 的遗留代码上,几乎不可能在不进行一些返工的情况下开始插入测试用例。有了 DI 并且只要在 DI 连接所有东西的地方正确使用它,即使在可能非常难看的遗留代码上也很容易做到这一点。
在许多 DI 框架中,您可以将生产模块用于您的测试,并使用一个测试模块覆盖与模拟对象的特定绑定(保留其余的接线)。这些可能是系统测试而不是单元测试,但我倾向于比普通开发人员更喜欢更高级别的测试,因为它测试类之间的集成,对于加入项目并可以看到整个功能的人来说,它是一个很好的文档(而不是只是部分功能),而无需设置整个系统)。