Инъекция зависимостей в трехслойном приложении 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 для создания определенного набора классов логики и репозитория.