2012-04-19 3 views
2

У меня есть интерфейс IDataContext, реализованный в InMemoryDataContext и MyApplicationDataContext. Это потребляется все из моих хранилищ, которые определяются как BananaRepository : IBananaRepository и принимают контекст данных в их конструктору:Контекстная/условная инъекция зависимостей с глубиной более 1 с помощью Ninject?

interface IDataContext {} 
class InMemoryDataContext : IDataContext {} 
class MyApplicationDataContext : IDataContext {} 

interface IBananaRepository {} 
class BananaRepository : IBananaRepository 
{ 
    public BananaRepository(IDataContext dataContext) {} 
} 

До сих пор мои потребители интерфейсов и услуг являются контроллерами ASP.NET MVC, синхронные команды и запросы. NInject настроен в моем веб-проекте, а IDataContext привязан к MyApplicationDataContext с InRequestScope().

kernel.Bind<IDataContext>().To<MyApplicationDataContext>().InRequestScope(); 
kernel.Bind<IBananaRepository>().To<BananaRepository>(); 

Я достиг точки в эволюции моего проекта, где я хочу, чтобы начать добавлять асинхронную обработку (команды, событие + обработчик и т.д.). Проблема, с которой я сталкиваюсь, заключается в том, что для тех, кому я должен получить переходный процесс IDataContext (новый каждый раз), но привязка уже настроена для экземпляра IDataContext для каждого запроса для моих контроллеров.

Рассмотрим простой сценарий, где моя DoSomethingAsyncCommand будет выполняться в новом потоке:

class DoSomethingAsyncCommand : IAsyncCommand<TArgs> 
{ 
    public DoSomethingAsyncCommand(IBananaRepository repository) {} 

    public bool Execute(TArgs args) {} 
} 

Я хочу, чтобы, когда Ninject экземпляр класса реализаций IAsyncCommandIBananaRepository (и все мои другие репозитории), чтобы инициализировать с новый экземпляр IDataContext, а не один для веб-запроса для повторного использования (фактически я хочу для IAsyncCommand мой IDataContext быть связанным, как InTransientScope())

Как я могу это сделать?

P.S: Я использую CommonServiceLocator, а не ядро ​​Ninject, непосредственно для создания экземпляров IAsyncCommand.

+0

Не будет просто «kernel.Bind (). () .InInjectedInto (). InTransientScope();" обязательный делать? – Hari

+0

@Hari Нет, потому что контекст вводится в репозиторий не в команде. –

ответ

2

Посмотрите на https://github.com/ninject/ninject/blob/master/src/Ninject/Planning/Bindings/BindingConfigurationBuilder.cs

Там вы найдете IsAnyAnchestorNamed. Вы можете использовать тот же цикл и объединить его с условием, которое вы найдете в InInjectedInto, и вызвать его из custom When.

+0

Спасибо - я рассмотрю реализацию этого позже сегодня и вернусь к вам (и этот вопрос/ответ). –

+0

Hm. Поэтому, если я сделаю эту работу и буду иметь «pbulic DoSomethingAsyncCommand (IRepo1 repo1, IRepo2 repo2)», и я использую «TransientScope», он фактически создаст два экземпляра «IDataContext»? Как мне обойти это? –

+0

Является ли это просто мной или то, что я думаю, будет невозможно, потому что, когда создается контекст данных, ссылка на репозиторий отсутствует или на команду для использования в качестве объекта области видимости? Думаю, мне лучше использовать Factory в моем сценарии? –

 Смежные вопросы

  • Нет связанных вопросов^_^