2016-05-06 5 views
0

Ниже мой регистр кодФабрика метод вызывается только один раз

container.RegisterType<IFoo, Foo>(
        new InjectionConstructor(typeof (IEnumerable<int>), 
         new ResolvedParameter<IBar1>, 
         new InjectionParameter<IBar2>(CreateBar2(container))) 

Проблема в CreateBar2(container) вызывается только один раз при старте программы, мне нужно назвать каждый IFoo решена

Другим вопросом, какой из них лучше практик

container.RegisterType<IFoo, Foo>(
        new InjectionConstructor(typeof (IEnumerable<int>), 
         new ResolvedParameter<IBar1>, 
         new InjectionParameter<IBar2>(CreateBar2(container))) 

или

container.RegisterType<IFoo, Foo>(
        new InjectionConstructor(typeof (IEnumerable<int>), 
         new ResolvedParameter<IBar1>, 
         CreateBar2(container)) 

ответ

0

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

container.RegisterType<IFoo, Foo>(
         new InjectionConstructor(typeof (IEnumerable<int>), 
          new ResolvedParameter<IBar1>, 
          new InjectionParameter<IBar2>(CreateBar2(container)), 
          new TransientLifetimeManager()) 

Это означает, что каждый раз, когда IFoo впрыскивается или разрешено будет вызывать конструктор каждый раз. Однако, похоже, вы вводите метод, который будет выполнен при регистрации - CreateBar2(container). Это то же самое, как написание:

var bar2 = CreateBar2(container); // Called once. 
container.RegisterType<IFoo, Foo>(
        new InjectionConstructor(typeof (IEnumerable<int>), 
         new ResolvedParameter<IBar1>, 
         new InjectionParameter<IBar2>(bar2)) 

Я рекомендую абстрагироваться это в классе, а не нагнетают его. Таким образом, вы также можете контролировать вызовы.

public interface ICreateBar2 
{ 
    IBar CreateBar2(); 
} 

public class CreateBar2 
{ 
    private IUnityContainer _container; 

    public CreateBar(IUnityContainer container) 
    { 
     _container = container; 
    } 

    public IBar CreateBar2() 
    { 
     // Do stuff. 
     return CreateBar2(_container); // Or what you need to do? 
    } 
} 

И изменить вашу регистрацию на

container.RegisterType<IFoo, Foo>(
        new InjectionConstructor(typeof (IEnumerable<int>), 
         new ResolvedParameter<IBar1>, 
         new ResolvedParameter<ICreateBar2>), 
         new TransientLifetimeManager()) 

container.RegisterType<ICreateBar2, CreateBar2>(new TransientLifetimeManager()); 

Или, возможно, RegisterInstance, если она лучше подходит для ваших потребностей?

Не забудьте заменить конструктор IFoo вместо ICreateBar. Самое лучшее с этим подходом в том, что вам больше не нужен InjectionConstructor, так как все параметры могут быть разрешены Unity.

container.RegisterType<IFoo, Foo>(new TransientLifetimeManager()); 

Если вы действительно должны держать CreateBar2() -метода в текущей области, вы можете придать Func, который фактически возвращает то же значение, как CreateBar2().

Я не знаю полностью подпись CreateBar(), но вы можете сделать что-то вроде этого:

container.RegisterType<IFoo, Foo>(
        new InjectionConstructor(typeof (IEnumerable<int>), 
         new ResolvedParameter<IBar1>, 
         new InjectionParameter<Func<IBar2>>(
          new Func<IBar2>(()=> CreateBar2(container))); 

Но теперь вам нужно вводить Func<IBar2> в IFoo конструктора. Это заставит его выполнять всякий раз, когда вы используете его в конструкторе.

public class Foo : IFoo 
{ 
    IBar1 _bar1; 
    IBar2 _bar2; 

    public Bar(IBar1 bar1, Func<IBar2> bar2Func) 
    { 
     _bar1 = bar1; 
     _bar2 = bar2Func(); 
    } 
} 
+0

Использование фабричной инъекции помогло, LifetimeManager не сделал этого и, как я знаю, тип по умолчанию - TransientLifetimeManager. – kvuong

+0

Да. По умолчанию lifetimemanager является временным. – smoksnes

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

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