2016-05-06 95 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

首先,您需要使用不同的LifetimeManagerTransientLifetimeManager每次都會解析一個新實例。

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

是的。默認的終身管理者是暫時的。 – smoksnes