2017-04-02 5 views
0

Wenn Func<T> ausgewertet wird, wo T mit InstancePerMatchingLifetimeScope innerhalb einer Singleton-Klasse registriert ist, sollte es nicht dieselbe Instanz bereitstellen? das heißt, sollte nicht Func<T> "Scope-aware" sein?Autofac Func <T> mit InstancePerMatchingLifetimeScope

Vielleicht wäre ein Beispiel besser.

Ich habe zwei Klasse:

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); 
     } 
    } 

die wie folgt registriert werden:

 var builder = new ContainerBuilder(); 

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

     var container = builder.Build(); 

Und ich bin das folgende Stück Code ausgeführt wird:

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

     singleton.Do(); 

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

      scoped.Num = 1; 

      singleton.Do(); 
     } 

Ich würde erwarten, dass der erste Anruf an Do() würde 0 drucken, und die zweite drucken: 1.

Ich musste geändert MySingleton zu InstancePerDependency so würde es funktionieren, was eine schlechte Lösung für mich ist, weil MySingleton teuer sein kann, zu schaffen.

Was fehlt mir hier?

+0

Es ist das normale Verhalten. Sie registrieren 'MyScoped' mit' InstancePerMatchingLifetimeScope' von "MyScope" und dann "root". * Autofac * sucht zuerst nach dem ersten übereinstimmenden Lebensdau- erscope, der "MyScope" ist, und schaut dann nach, ob in diesem Bereich "MyScoped" vorhanden ist. Wenn nicht, wird ein neues erstellt. Wenn Sie "MyScope" in Ihrer 'InstancePerMatchingLifetimeScope'-Deklaration entfernen, funktioniert es wie erwartet. Kannst du uns erklären, was du versuchst? –

Antwort

0

Es scheint, dass Dienste, die als einzelne Instanz registriert sind, im Kontext des Root-Bereichs aufgelöst werden. Es bedeutet, dass Ihre Func<MyScoped> injiziert zu MySingleton immer MyScoped von der Wurzel auflösen würde. Der folgende Code:

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(); 
} 

würde 1 zweimal drucken, weil var scopedObj = scoped(); in Do() Verfahren MyScoped aus Stammcontainer lösen würde, nicht aus dem Umfang.

könnten Sie erreichen, was Sie wollen, indem erforderliche Abhängigkeit Methode manuell in Do() vorbei:

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); 
} 

Es 1 und 10 bzw. drucken.

+0

Leider ist dies keine gute Lösung IMO. Das würde erfordern, dass ich die Abhängigkeit vom gesamten Stack herkopple. – Elad

Verwandte Themen