Предварительные сведения
- Я использую Ninject.MVC3 2.2.2.0 Nuget Package для внедрения в мой контроллер реализации интерфейса IDomain, который разделяет мою бизнес-логику (BL) с использованием подхода Factory.
Я регистрирую свои Ninject-модули в предварительно настроенном NinjectMVC3.cs , используя:
private static void RegisterServices(IKernel kernel)
{
var modules = new INinjectModule[]
{
new DomainBLModule(),
new ADOModule()
};
kernel.Load(modules);
}
Я пытаюсь избежатьроковое проклятие дьявольского Service Locator anti-pattern.
Класс домена использует DBContext, который я тоже пытаюсь внедрить в реализацию интерфейса черезIDBContext, со следующим сценарием:
IDomainBLFactory :
public interface IDomainBLFactory
{
DomainBL CreateNew();
}
DomainBLFactory :
public class DomainBLFactory : IDomainBLFactory
{
public DomainBL CreateNew()
{
return new DomainBL();
}
}
В пространстве имен контроллера:
public class DomainBLModule : NinjectModule
{
public override void Load()
{
Bind<IDomainBLFactory>().To<DomainBLFactory>().InRequestScope();
}
}
На этом этапе я могу внедрить реализацию IDomainBLFactory в мой контроллер с помощью Ninject Constructor Injection без каких-либо проблем:
public class MyController : Controller
{
private readonly IDomainBLFactory DomainBLFactory;
// Default Injected Constructor
public MyController(IDomainBLFactory DomainBLFactory)
{
this.DomainBLFactory = DomainBLFactory;
}
... (use the Domain for performing tasks/commands with the Database Context)
}
Теперь моя центральная проблема.
В ДоменеРеализация BL, я добавлю зависимость к определенному DBContext, в этом случае ADO DBContext из Entity Framework, снова, используя IDBContextFactory:
IDbDataContextFactory
public interface IDbDataContextFactory
{
myADOEntities CreateNew();
}
DbDataContextFactory
public class DbDataContextFactory : IDbDataContextFactory
{
public myADOEntities CreateNew()
{
return new myADOEntities ();
}
}
ADOModule
public class ADOModule : NinjectModule
{
public override void Load()
{
Bind<IDbDataContextFactory>().To<DbDataContextFactory>().InRequestScope();
}
}
Теперь в реализации DomainBL я столкнулся с проблемой внедрения необходимого интерфейса для объекта DBContextФабрика:
public class DomainBL
{
private readonly IDbDataContextFactory contextFactory;
**** OPS, i tried to understand about 10+ Stackoverflow articles ***
...
}
Что я пробовал?
Использовать конструктор Injection .Но я не знаю, что добавить в вызов для Factory CreateNew () в IDBContextFactory.Для ясности:
public class DomainBLFactory: IDomainBLFactory
{
// Here the constructor requires one argument for passing the factory impl.
public DomainBL CreateNew()
{
return new DomainBL(?????) // I need a IDBContextFactory impl to resolve.
//It's not like in the MVC Controller where injection takes place internally
//for the controller constructor. I'm outside a controller
}
}
В этом Полезном посте , наш уникальный верный друг Ремо Глур описывает в комментарии возможное решение для меня, цитируя: " Создайте интерфейс с методом CreateSomething, который берет все необходимое для создания экземпляра и возвращает его. Затем в вашей конфигурации вы реализуете этот интерфейс и добавляете IResolutionRoot в его конструктор и используете это instace для получения требуемого объекта . "
Вопросы : Как правильно реализовать это, используя Ninject.MVC3 и мой скромный подход к классу доменов?Как разрешить IResolutionRoot без наказания за ретрансляцию в анти-шаблоне Service Locator?
Чтобы использовать внедрение свойства для IDBContexFactory .В ходе изучения и чтения всех противоречивых точек зрения, а также теоретических объяснений, я могу сделать вывод, что это не правильный способ внедрения кода для моего класса DBContexFactory.Не берите в голову.Все равно не работает.
public class DomainBL
{
[Inject]
public IDbDataContextFactory contextFactory
{
get;
set;
}
//Doesn't works, contextFactory is null with or without parameterless constructor
.... (methods that uses contextFactory.CreateNew()....
}
Вопрос: Что мне не хватает?Даже если этот подход неверен, свойство не вводится.
Будь проклят .Используйте DependencyResolver и живите со стигматами.Это работает, и я останусь в этом подходе, пока для меня не появится правильное решение.И это действительно расстраивает, потому что из-за недостатка знаний в последние 10 дней я пытался понять и поступить правильно.
public class DomainBL
{
private readonly IDbDataContextFactory contextFactory;
this.contextFactory = DependencyResolver.Current.GetService<IDbDataContextFactory>();
//So sweet, it works.. but i'm a sinner.
}
Вопрос: Есть ли большая ошибка в моем пониманииФабричный подход для внедрения сопряженных реализаций и с использованием доменного подхода для разделения бизнес-логики?В случае, если я ошибаюсь, какой набор шаблонов я должен реализовать с уверенностью?
Я видел перед действительно большим количеством статей и блогов, которые не задают этот важный вопрос открыто и ясно.
RemoGloor представляет Ninject.Extensions.Factory для Ninject 3.0.0 RC на сайте www.planetgeek.ch/2011/12/31/ninject-extensions-factory-introduction.
Вопрос: Будет ли работать это расширение в сочетании с Ninject.MVC3 для обычного porpouse ?.В таком случае это должна быть моя надежда на ближайшее будущее.
Спасибо всем заранее за ваше руководство и помните, что мы ценим вашу любезную помощь.Я думаю, что многие найдут этот сценарий полезным.