2013-08-12 4 views
1

Я не уверен, как сделать именованную зависимость с единством, чтобы следовать за другим пути разрешения. Так что, если у меня естьUnity IoC - разрешить именованную зависимость другой путь

public interface IService 
{ 
    SomeMethod(); 
} 

public class Service : IService 
{ 
    private readonly IRepository repository; 
    public Service(IRepository repository) 
    { 
    this.repository = repository; 
    } 
    public SomeMethod 
    { 
     //some implementation here 
    } 
} 

и под меня Repository: IRepository, NHibernateContext: INHibernateContext, ISession и т.д.

Мой вопрос, если я сделать следующий шаг в моей Global.asax:

container.RegisterType<IService, Service>("GlobalContext"); 

, то как мне заставить его вставлять NHibernateContext (или некоторую другую иерархическую зависимость) в путь «GlobalContext» (не используя зарегистрированный по умолчанию тип)?

Справка очень ценится.

ответ

0

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

  1. Создать дочерний контейнер и зарегистрировать зависимости имеющих различное разрешение
  2. сам Регистр ребенка контейнер в качестве имени экземпляра.
  3. В точке входа (на моем контроллере контроллера) проверьте, нужно ли разрешать через родительский контейнер или дочерний элемент. При необходимости разрешите дочерний контейнер и разрешите цепочку иерархии, используя его. Если регистрация в дочернем контейнере не существует, он будет использовать родительский зависимый преобразователь.
2

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

container.RegisterType<INHibernateContext, NHibernateContext>("GlobalContext"); 
container.RegisterType<ISession, NHibernateSession>("GlobalContext"); 

И когда вы разрешить IRepository, «GlobalContext» Вы хотите, чтобы эта конкретная зависимость впрыскивается. Предполагая, что у вас есть конструктор, который принимает эти два параметра, вы явно указать контейнер, название которого вы хотите использовать:

container.RegisterType<IRepository, Repository>("GlobalContext", 
    new InjectionConstructor(
     new ResolvedParameter<INHibernateContext>("GlobalContext"), 
     new ResolvedParameter<ISession>("GlobalContext") 
    ) 
); 

Это говорит контейнер использовать конструктор, который принимает INHibernateContext и ISession, чтобы решить эти параметры через контейнер, и используйте имя GlobalContext при их разрешении.

Аналогично, чтобы подключить вашу услугу:

container.RegisterType<IService, Service>("GlobalContext", 
    new ResolvedParameter<IRepository>("GlobalContext") 
); 

И окончательный вызов постановляю:

container.Resolve<IService>("GlobalContext"); 

должен построить свой объект граф, как вы хотите.

+0

Thanks @Chris, я надеялся, что мне не нужно будет проходить через всю иерархию инжекции, установив каждый инжекторный конструктор отдельно (у меня есть 4 уровня впрыска atm, но представьте, что бы это было в более сложном сценарии). –

+0

Возможно, что-то в новой версии Unity 3.0, связанной с регистрацией, может помочь? Я еще не использовал его, поэтому не могу сказать точно. –