Как организовать использование DI Framework в приложении? - PullRequest
1 голос
/ 21 февраля 2012

EDIT: я забыл переместить ядро ​​в неуниверсальный родительский класс и предоставить виртуальный метод для доступа к нему.Я понимаю, что приведенный ниже пример создаст множество экземпляров ядра.

Я только что узнал, как сделать инъекцию на прошлой неделе, и вот как у меня все настроено:

using Ninject;
using System.Reflection;

namespace Infrastructure
{
    public static class Inject<T>
    {
        static bool b = Bootstrap();
        static IKernel kernel;

        static bool Bootstrap()
        {
            kernel = new StandardKernel();
            kernel.Load(Assembly.GetExecutingAssembly());
            return true;
        }

        public static T New() { return kernel.Get<T>(); }
    }
}

А затем я планирую сделать различные классы модулей ninject частью пространства имен инфраструктуры, чтобы они загружались.

Мне не удалось найти здесь или в Google что-либо, что даетпримеры того, как на самом деле организовать использование Ninject в вашем проекте, но мне это кажется правильным, так как в этой сборке мне нужна только ссылка на Ninject.Это более или менее «правильный» способ или лучший дизайн?

1 Ответ

4 голосов
/ 21 февраля 2012

Есть несколько проблем с тем, как вы делаете вещи сейчас.

Позвольте мне сначала начать с очевидной проблемы C #: переменные статического класса в универсальных классах совместно используются на основе T.Другими словами, Inject<IUserRepository> и Inject<IOrderRepository> каждый получит свой собственный экземпляр IKernel, что маловероятно, что вы действительно хотите, так как, скорее всего, вам понадобится один IKernel для срока службы вашего приложения.Если у вас нет единственного IKernel для приложения, невозможно зарегистрировать типы как синглтон, так как синглтон всегда ограничен областью на уровне контейнера, а не на уровне приложения.Итак, вам лучше переписать класс как неуниверсальный и переместить аргумент универсального типа в метод:

Inject.New<T>()

Вторая проблема связана с внедрением зависимостей.Мне кажется, вы пытаетесь использовать анти-шаблон Service Locator , поскольку вы, вероятно, явно вызываете Inject.New<T> из своего приложения.На контейнер DI следует ссылаться только в начальном пути приложения, и он должен иметь возможность построить полный граф объектов связанных объектов.Таким образом, вы можете попросить контейнер получить объект корневого уровня для вас (например, Controller в контексте MVC), а остальная часть приложения не будет обращать внимания на использование любой технологии DI.Когда вы делаете это, нет необходимости абстрагироваться от использования контейнера (как вы делали с вашим Inject классом).

Не все технологии приложений или пользовательского интерфейса допускают это BTW.Я склонен скрывать свой контейнер (так же, как вы делаете) при работе с приложением Web Forms, потому что невозможно сделать правильное внедрение зависимостей для Page классов, IHttpHandler объектов и UserControl классов.

...