首页 文章

Ninject模块的目的是什么?

提问于
浏览
58

我是ninject的完全新手

我一直在拉开其他人的代码,发现了几个nInject模块实例 - 从Ninject.Modules.Module派生的类,并且有一个包含大部分代码的加载方法 .

通过调用StandardKernel实例的LoadModule方法并将其传递给模块类的实例来调用这些类 .

也许我在这里遗漏了一些明显的东西,但是这对于创建一个普通的旧类并调用它的方法,或者使用静态方法的静态类有什么好处呢?

3 回答

  • 61

    也许我在这里遗漏了一些明显的东西,但是这对于创建一个普通的旧类并调用它的方法,或者使用静态方法的静态类有什么好处呢?

    对我们来说,能够很容易地在以后添加测试 . 只需用mockobjects覆盖一些绑定,然后在没有连接“一切”的DI的情况下对遗留代码进行覆盖,几乎不可能在没有一些返工的情况下插入测试用例 . 使用DI并且只要在DI连接所有内容的情况下正确使用它,即使在可能非常难看的遗留代码上也很简单 .

    在许多DI框架中,您可以使用 生产环境 模块进行测试,使用测试模块覆盖与mockobjects的特定绑定(保留其余的布线) . 这些可能是系统测试而不是单元测试,但我倾向于比普通开发人员更喜欢更高级别的测试,因为它测试了类之间的集成,对于加入项目并可以看到整个功能的人来说,它是很好的文档(而不是只需部分功能)而无需设置整个系统) .

  • 3

    也许我在这里遗漏了一些明显的东西,但是这对于创建一个普通的旧类并调用它的方法,或者使用静态方法的静态类有什么好处呢?

    是的,您可以调用一堆 Bind<X>().To<Z>() 语句来设置绑定,而无需模块 .

    不同之处在于,如果您将这些语句放在一个模块中,那么:

    • IKernel.Load(IEnumerable<Assembly>) 可以通过反射动态发现这些模块并加载它们 .

    • 绑定在名称下逻辑分组在一起;您可以使用此名称再次使用 IKernel.Unload(string) 卸载它们

  • 9

    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>();
    

相关问题