Как сохранить контейнер IoC в одном месте, в то время как внутренним классам нужно создавать зависимости после создания - PullRequest
5 голосов
/ 30 марта 2011

Я начал использовать Ninject, в этом относительно небольшом проекте, и столкнулся с проблемой: у меня есть этот класс

class SomeService : ISomeService 

это зависит от

class BizLogicModule : IBizLogicModule

что в свою очередь зависит от

class DataRepository : IDataRepository

DataRepository имеет ctor, который выглядит следующим образом:

DataRepository(BizEntityModel context)

Теперь мне нужно иметь возможность использовать один экземпляр BizEntityModel на нескольких экземплярах IDataRepository.
Мне также нужно создать IDataRepository на протяжении жизни IBizLogicModule. IBizLogicModule не знает о Ninject, и я хочу сохранить его таким.

поэтому моя проблема: как подключить все это, используя ядро ​​Ninject, в то время как:

  1. не нужно передавать экземпляр ядра вокруг слоев.

  2. оставляя читаемый код близким к тому, что был до Ninject (я только что начал использовать фабричный метод).

Простая часть проводки, которую я получил до сих пор:

Bind<SomeService>().To<ISomeService>();
Bind<BizLogicModule>().To<IBizLogicModule>();
Bind<DataRepository>().To<IDataRepository>(); 
Bind<BizEntityModel>().To<BizEntityModel>(); //ToSelf()
// .WithConstructorArgument(context => Kernel.Get<BizEntityModel>)

Ваше руководство очень ценится

РЕДАКТИРОВАТЬ: Спасибо за ваши ответы!
Вот еще некоторые данные, которые были запрошены: BizEntityModel зарегистрировано в Ninject (код обновлен).

если я правильно понимаю: я могу создать экземпляры IDataRepository в IBizLogicModule, используя «фабричный метод». но это оставляет меня с:
1) Мне нужно передать BizEntityModel фабричному методу, иногда его отруби, а иногда и существующий экземпляр. используя фабричный метод, он будет создавать заново каждый раз.
2) это проблема, что SomeService находится в другой сборке, и только он имеет ссылку на Ninject.dll?

Ответы [ 3 ]

2 голосов
/ 30 марта 2011

Я повторяю вопрос, как я понял:

  1. Ровно один экземпляр BizEntityModel существует на экземпляр BizLogicModule (они не имеют ссылки друг на друга)

  2. Всякий раз, когда BizLogicModule создает хранилище данных, этот BizEntityModel используется повторно

  3. Есть несколько BizLogicModules

Если это правильно, второй примерв расширении NamedScope документация должна соответствовать вам.См. https://github.com/ninject/ninject.extensions.namedscope/wiki/InNamedScope

Убедитесь, что вы прочитали полный документ этого расширения: https://github.com/ninject/ninject.extensions.namedscope/wiki

1 голос
/ 30 марта 2011

Вы регистрируете BizEntityModel в Ninject? Если это так, вы сможете указать Ninject предоставлять один и только один экземпляр BizEntityModel для каждого запроса на время существования контейнера или даже программы, без необходимости определять и регистрировать традиционный одноэлементный экземпляр BizEntityModel. Даже если вам придется работать с фабричным методом, а Ninject не позволит вам зарегистрировать эту единичную область действия, при необходимости вы можете загрузить объект с нетерпением и затем зарегистрировать экземпляр для зависимости как одиночный.

IBizLogicModule никогда не должен знать о Ninject; Ninject должен знать о BizLogicModule. Попробуйте создать регистрацию IDataRepository, которая предоставит фабричный метод (с фабричной областью, так что для каждого вызова создается новый экземпляр), а затем передайте этот фабричный метод как зависимость IBizLogicModule, который будет использовать его, когда ему необходимо создать IDataRepositories. Вы в основном проходите через возможности разрешения IoC, чтобы предоставить фабричный класс в IBizLogicModule. Если вы делаете это для большого количества различных типов классов в IBizLogicModule, вы в основном создаете локатор служб, которого я лично избегал бы, но один или два - это совершенно правильный шаблон Factory / Creator.

0 голосов
/ 30 марта 2011

В приведенном ниже ответе предполагается, что вы спрашиваете, как разрешить множество экземпляров IDataRepository в одном IBizLogicModule.В противном случае этот вопрос будет слишком простым: -)

Обычно хорошие контейнеры IoC имеют возможность внедрять методы фабрики / фабрики.У меня нет большого опыта работы с NInject, и я не нашел столь хороших решений, как я знаю, для других контейнеров, но ЗДЕСЬ вы можете увидеть пример того, как можно решить основную задачу.Единственная проблема здесь заключается в том, что вам придется реализовать фабрику самостоятельно и вытянуть туда IResolutionContext, но в любом случае эта фабрика позволит вам изолировать остальную часть вашего кода (IBizLogicModule) от особенностей IoC, поскольку она будет иметь только IDataRepositoryFactoryзависимость.

...