Каковы намерения модулей Ninject?

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

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

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

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

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.

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

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

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

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

Другие вопросы по тегам