我是ninject的完全新手
我一直在拉开其他人的代码,发现了几个nInject模块实例 - 派生自Ninject.Modules.Module的类,并且有一个包含大部分代码的加载方法。
通过调用StandardKernel实例的LoadModule方法并向其传递模块类的实例来调用这些类。
也许我在这里遗漏了一些明显的东西,但是这样做的好处是什么只是创建一个普通的旧类并调用它的方法,或者可能是静态类的静态类?
答案 0 :(得分:61)
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>();
答案 1 :(得分:9)
也许我错过了一些明显的东西 在这里,但这有什么好处 只是创造一个普通的老班 并调用它的方法,或者也许是一个 静态类与静态方法?
是的,您可以调用一堆Bind<X>().To<Z>()
语句来设置绑定,而无需模块。
不同之处在于,如果您将这些语句放在模块中,那么:
IKernel.Load(IEnumerable<Assembly>)
可以通过反射动态发现这些模块并加载它们。IKernel.Unload(string)
答案 2 :(得分:3)
也许我在这里遗漏了一些明显的东西,但是这样做的好处是什么只是创建一个普通的旧类并调用它的方法,或者可能是静态类的静态类?
对我们来说,能够很容易地在以后添加测试。只需使用mockobjects覆盖一些绑定,并且在遗留代码上没有连接“一切”的DI,几乎不可能在没有一些返工的情况下插入测试用例。使用DI并且只要在DI连接所有内容的情况下正确使用它,即使在可能非常难看的遗留代码上也很简单。
在许多DI框架中,您可以使用生产模块进行测试,使用测试模块覆盖与mockobjects的特定绑定(保留其余的布线)。这些可能是系统测试而不是单元测试,但我倾向于比普通开发人员更喜欢更高级别的测试,因为它测试类之间的集成,对于加入项目并可以看到整个功能的人来说,它是很好的文档(而不是只需部分功能)而无需设置整个系统。)