2017-04-02 74 views
0

在評估Func<T>其中T是在InstancePerMatchingLifetimeScope中註冊的,在單例類中,它不應該提供相同的實例嗎?也就是說,不應該Func<T>是「範圍感知」?Autofac Func <T> with InstancePerMatchingLifetimeScope

也許一個例子會更好。

我有兩個類:

class MyScoped 
    { 
     public int Num { get; set; } 
    } 

    class MySingleton 
    { 
     readonly Func<MyScoped> scoped; 

     public MySingleton(Func<MyScoped> scoped) 
     { 
      this.scoped = scoped; 
     } 

     public void Do() 
     { 
      var scopedObj = scoped(); 

      Console.WriteLine(scopedObj.Num); 
     } 
    } 

哪些是註冊這樣的:

 var builder = new ContainerBuilder(); 

     builder.RegisterType<MyScoped>().InstancePerMatchingLifetimeScope("MyScope", "root"); 
     builder.RegisterType<MySingleton>().SingleInstance(); 

     var container = builder.Build(); 

而且我運行下面的代碼:

 var singleton = container.Resolve<MySingleton>(); 

     singleton.Do(); 

     using (var scope = container.BeginLifetimeScope("MyScope")) 
     { 
      var scoped = scope.Resolve<MyScoped>(); 

      scoped.Num = 1; 

      singleton.Do(); 
     } 

我期望第一次撥打Do()將打印0,第二次打印將打印1.

我不得不改變MySingletonInstancePerDependency所以它會工作,這對我來說是一個壞的解決方案,因爲MySingleton可以創建昂貴。

我在這裏錯過了什麼?

+0

這是正常的行爲。您使用「MyScope」的InstancePerMatchingLifetimeScope和「root」註冊「MyScoped」。 * Autofac *將首先查找第一個匹配的生命週期「MyScope」,然後查看該範圍內是否有任何「MyScoped」實例。如果不是,它會創建一個新的。如果您在「InstancePerMatchingLifetimeScope」聲明中刪除「MyScope」,它將按預期工作。你能向我們解釋你想做什麼嗎? –

回答

0

看起來作爲單個實例註冊的服務在根作用域的上下文中解決。這意味着您注入MySingletonFunc<MyScoped>將始終從根目錄解析MyScoped。以下代碼:

var singleton = container.Resolve<MySingleton>(); 
var s = container.Resolve<MyScoped>(); 

s.Num = 1; 

singleton.Do(); 

using (var scope = container.BeginLifetimeScope("MyScope")) 
{ 
    var scoped = scope.Resolve<MyScoped>(); 

    scoped.Num = 10; 

    singleton.Do(); 
} 

將打印1次,因爲在var scopedObj = scoped();方法Do()將從根容器解決MyScoped,不脫離本發明範圍。

你可以達到你想要的東西通過傳遞需要依賴手動進Do()方法:

class MySingleton 
{ 
    public void Do(MyScoped myScoped) 
    { 
     Console.WriteLine(myScoped.Num); 
    } 
} 

// ... 

var singleton = container.Resolve<MySingleton>(); 
var s = container.Resolve<MyScoped>(); 

s.Num = 1; 

singleton.Do(s); 

using (var scope = container.BeginLifetimeScope("MyScope")) 
{ 
    var scoped = scope.Resolve<MyScoped>(); 

    scoped.Num = 10; 

    singleton.Do(scoped); 
} 

這將分別打印110

+0

不幸的是,這不是一個好的解決方案IMO。這將需要我依賴於整個堆棧的依賴關係。 – Elad

相關問題