Что такое намерение модулей Ninject?


Я полный новичок в ninject

я разбирал чужой код и нашел несколько экземпляров модулей nInject - классов, производных от Ninject.Модули.Модуль, и есть метод загрузки, который содержит большую часть их кода.

эти классы вызываются путем вызова метода LoadModule экземпляра StandardKernel и передачи ему экземпляра класса module.

может быть, я упускаю что-то очевидное, но что это преимущество этого над просто созданием простого старого класса и вызовом его метода или, возможно, статического класса со статическим методом?

3 58

3 ответа:

модули 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.

остальные из вас вопрос звучит так, как будто это больше о МОК и Ди в целом, а не только 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)

может быть, я упускаю что-то очевидное здесь, но в чем преимущество этого над просто созданием простого старого класса и вызовом его метода или, возможно, статического класса со статическим методом?

для нас это возможность добавлять тесты в более позднее время очень легко. Просто переопределите несколько Привязок с помощью mockobjects и voila.....в устаревшем коде без DI, который подключил "все", почти невозможно начать вставку тестовых случаев без некоторой доработки. С Ди на месте и до тех пор, пока он использовался правильно, где DI подключил все, это очень просто сделать даже на устаревшем коде, который может быть очень уродливым.

во многих системах DI вы можете использовать производственный модуль для вашего теста с тестовым модулем, который переопределяет определенные привязки с помощью mockobjects(оставляя остальную часть проводки на месте). Это могут быть системные тесты больше, чем модульные тесты, но я предпочитаю тесты более высокого уровня, чем средний разработчик, поскольку он тестирует интеграцию между классами и это отличная документация для тех, кто присоединяется к проекту и может видеть всю функцию в действии(а не только части функции) без необходимости настройки всей системы).