2012-02-23 102 views
1

我昨天試圖提出這個問題,並沒有完全說明問題。所以我製作了一個複製品來展示我的問題。註冊級聯依賴關係(Take 2)

在下面的程序中,我正在解決吧女巫應該注入Foo和Fool。傻瓜也注入了Foo。我想要Bar和Fool都使用相同的Foo。在下面的代碼中沒有發生。

class Program 
{ 
    static void Main(string[] args) 
    { 
     IUnityContainer container = new UnityContainer(); 

     Console.WriteLine("Resolving Bar"); 
     container.Resolve<Bar>(); 
     Console.ReadLine(); 
    } 
} 

public class Foo 
{ 
    public Foo() 
    { 
     Console.WriteLine("Foo created " + this.GetHashCode()); 
    } 
} 

public class Fool 
{ 
    public Foo Foo { get; set; } 
    public Fool(Foo foo) 
    { 
     Foo = foo; 
     Console.WriteLine("Fool created with injected Foo " + foo.GetHashCode()); 
    } 
} 
public class Bar 
{ 
    public Bar(Foo foo, Fool fool) 
    { 
     Console.WriteLine("Bar created with injected Foo " + foo.GetHashCode()); 
     Console.WriteLine("Bar created with injected Fool.Foo " + fool.Foo.GetHashCode()); 
     // I want foo == fool.Foo 
    } 
} 
public class Blat 
{ 
    public Blat(Foo foo, Fool fool) 
    { 
     Console.WriteLine("Blat created with injected Foo " + foo.GetHashCode()); 
     Console.WriteLine("Blat created with injected Fool.Foo " + fool.Foo.GetHashCode()); 
    } 
} 

我可以在Main方法中解析類型並定義一個特定的注入構造函數,但是我有一個複雜的問題。在這種情況下,我還創建了一個Blat以及一個Bar。我想要Blat和Bar使用不同的Foo。

考慮:

static void Main(string[] args) 
    { 
     IUnityContainer container = new UnityContainer(); 
     var foo = container.Resolve<Foo>(); 
     container.RegisterType<Fool>(new InjectionConstructor(foo)); 
     var fool = container.Resolve<Fool>(); 
     container.RegisterType<Bar>(new InjectionConstructor(foo, fool)); 
     container.RegisterType<Blat>(new InjectionConstructor(foo, fool)); 

     Console.WriteLine("Resolving Bar"); 
     container.Resolve<Bar>(); 
     container.Resolve<Blat>(); 
     Console.ReadLine(); 
    } 
} 

在這種情況下Bar.Foo == Bar.Fool.Foo但Blat.Foo == Bar.Foo。換句話說,我想 Bar.Foo == Bar.Fool.Foo & & Blat.Foo!= Bar.Foo

有沒有辦法做到這一點?我會解決許多類型的酒吧的和BLAT的,所以我想,以避免各酒吧,BLAT等創建子容器......

EDITTED進一步混淆問題

問題是,在現實世界我有類似如下:

BaseViewModel(Context context, ServiceA a, ServiceB b) 

每個控制都需要創建一個視圖模型,使用不同的上下文。在每個viewModel中,服務必須使用相同的上下文。所以我希望Unity使用相同的上下文創建上下文,a和b。

我可以做一些類似於你的建議。我可以在BaseViewModel的構造函數中的服務上設置Context屬性,但對我來說這似乎很奇怪。現在我只是在構造函數中創建服務,但我寧願使用Unity來完成,因此它們不會緊密耦合。我希望有一個更優雅的方式。

回答

2

有了您IUnityContainer,註冊FooPerResolveLifetimeManager,即:

static void Main(string[] args) 
{ 
    IUnityContainer container = new UnityContainer(); 
    container.RegisterType<Foo>(new PerResolveLifetimeManager()); 

    Console.WriteLine("Resolving Bar"); 
    container.Resolve<Bar>(); 
    container.Resolve<Blat>(); 
    Console.ReadLine(); 
} 

當您解決BarFoo相同的實例將被注入到Bar並注入Fool

然後,當您解析Blat時,Foo的新實例將被注入到BlatFool中。

所以Bar.Foo == Bar.Fool.FooBlat.Foo == Blat.Fool.FooBar.Foo != Blat.FooBar.Fool.Foo != Blat.Fool.Foo

每次調用container.Resolve時間,Foo只有一個實例是不斷解決該圖,那是什麼呢PerResolveLifetimeManager

0

你有沒有想過這樣的事情:

public class Bar 
{ 
    public Bar(Fool fool) 
    { 
    this.Fool = fool; 
    } 
    public Foo Foo 
    { 
    get { return this.Fool.Foo; } 
    set { this.Fool.Foo = value; } 
    } 
    public Fool Fool { get; set; } 
} 

其中Bar.FooBar.Fool.Foo只是一個方便的setter /吸氣?爲什麼要注入同一個實例兩次?

+0

看我編輯的解釋,爲什麼我兩次注入相同的實例 – foo 2012-02-23 21:22:48