Инъекция зависимостей в трехслойном приложении asp.net mvc

У меня есть 3-слойное приложение, а слои:

  • Web: Presentation Layer (ASP.NET MVC) → видит только BLL
  • BLL: Business Logic Layer → видит только DAL
  • DAL: Уровень доступа к данным

Итак, слой Web ничего не знает о моем слое DAL. У меня есть интерфейсы репозитория и конкретные классы в моем DAL, которые используются в слое BLL в классах бизнес-логики. Вопрос заключается в том, чтобы разделить DAL и BLL, как мне настроить Ninject для внедрения моих реализаций репозитория на уровень BLL?

Тот же вопрос относится к слою Web и BLL, у меня есть интерфейсы и реализации на BLL, которые я использую их в слое Web, как мне настроить Niject для этого?

Ответ 1

Идея заключается в том, что вы определяете интерфейсы для своих DAL и BLL. Затем вы берете экземпляр такого интерфейса, как параметр конструктора. Пример

interface IDatabase
{
    // Methods here
}

Ваш класс BLL:

public class Bll
{
    IDatabase _db;
    public Bll(IDatabase db)
    {
        _db = db;
    }

    public void SomeMethod()
    {
        // Use db here
    }
}

Затем в вашем корневом составе (в веб-приложении) вы используете ядро ​​для настройки этих зависимостей:

 kernel.Bind<IDatabase>().To<ConcreteDatabase();

Вам нужно то же самое от ваших контроллеров к вашему BLL, но он работает одинаково.

Кроме того, я думаю, что ваши зависимости неправильно настроены. В общем, вам не нужны эти вертикальные зависимости. Вы должны стремиться к более плоской иерархии. Я написал сообщение в блоге об этом: http://www.kenneth-truyers.net/2013/05/12/the-n-layer-myth-and-basic-dependency-injection/

В своем сообщении в блоге я объясню, в чем проблема с такой иерархией и как вы можете ее избежать. Кроме того, он описывает именно вашу проблему: ASP.NET MVC, BLL, DLL и Ninject, чтобы связать их вместе.

Ответ 2

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

В файле ninjectwebcommon в вашем веб-приложении используйте отражение, чтобы получить доступ к своим бизнес-уровням и уровням данных, чтобы вы могли загрузить все необходимое

Так же:

        System.Reflection.Assembly assembly;

        assembly = System.Reflection.Assembly.Load("our.biztier");
        kernel.Load(assembly);

        assembly = System.Reflection.Assembly.Load("our.datatier");
        kernel.Load(assembly);

Ninjects Метод "Загрузить" ищет любой класс в сборке, который наследует класс ninject "NinjectModule", а затем вызывает его для загрузки всего в ядро.

Таким образом, наши уровни бизнеса и данных содержат один простой класс инъекций, который мы используем для загрузки всего.

public class InjectionModuleBiz : NinjectModule
{


    public override void Load()
    {
        Kernel.Bind<ICustomerBiz>().To<CustomerBiz>().InRequestScope();
        Kernel.Bind<IEmployeeBiz>().To<EmployeeBiz>().InRequestScope();
    }
}

и у нас есть еще один класс injectionModule в нашем уровне данных

public class InjectionModuleData : NinjectModule
{


    public override void Load()
    {
        Kernel.Bind<ICustomerData>().To<CustomerData>().InRequestScope();
        Kernel.Bind<IEmployeeData>().To<EmployeeData>().InRequestScope();
    }
}

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

Надеюсь, что это поможет.

Ответ 3

Я согласен, что есть много путаницы, когда мы используем инъекцию зависимостей в приложениях N-Tier с помощью Visual Studio.

В основном потому, что в Visual Studio мы структурируем слои как разные проекты в решении и добавляем зависимости, ссылаясь на проект или DLL. Это совсем не так, как принципы понятий корневой структуры и состава.

Основной вопрос: какие зависимости мы вводим?

Бизнес-логика или репозиторий?

Если это репозиторий, да, вы правы, веб-слой не должен знать об этом. BLL выбирает репозиторий на основе определенных условий.

Если у нас есть полностью изолированные приложения, нам нужно установить DI на двух уровнях.

Вашему веб-приложению потребуется настроить ninject для создания ваших компонентов BLL. Приложение BLL установит ninject для создания определенного набора классов логики и репозитория.