2016-07-07 17 views
0

Kontext: Owin (self-host) + WebAPI + UseAutofacMiddleware + UseAutofacWebApiVerwalten Lebensdauer Scopes mit Autofac

Was ich versuche zu tun:

Registrieren Sie eine ILog Instanz in den App Start Containern.

Registrieren Sie für jede Anfrage eine neue ILog Instanz, die die "root" -Instanz umhüllt, sodass jede Middleware- und/oder pro-Anfrage-Dienste sie verwenden können.

var containerBuilder = new ContainerBuilder(); 
containerBuilder.RegisterInstance(log).As<ILog>(); 
containerBuilder.Register(ctx => { 
    var rootLog = ctx.Resolve<ILog>(); 
    return new PrependStringLog(rootLog, "request: "); 
}).InstancePerRequest(); 

jedoch beschwert Autofac über zirkuläre Abhängigkeiten beim Instanzieren Middleware ein ILog in ihrer Konstruktoren aufweist.

Wenn ich das "root log" nenne und mit dem gegebenen Namen auflösen, funktioniert alles wie erwartet.

containerBuilder.RegisterInstance(log) 
       .Named("root", typeof(ILog)); 
containerBuilder.Register(ctx => { 
    var rootLog = ctx.ResolveNamed<ILog>("root"); 
    return new PrependStringLog(rootLog, "request: "); 
}).InstancePerRequest(); 

Muss ich eine benannte Instanz verwenden, damit es funktioniert?

Antwort

1

Autofac verwendet den neuesten registrierten Dienst, wenn eine Komponentenanforderung für einen Dienst angefordert wird.

In Ihrem Fall die neueste ILog registriert ist ein Lambda-Ausdruck:

containerBuilder.Register(ctx => { 
    var rootLog = ctx.Resolve<ILog>(); 
    return new PrependStringLog(rootLog, "request: "); 
}).InstancePerRequest(); 

Diese Lambda-Ausdruck Anfrage ein ILog das, was Autofac ist zu bauen versucht: das ist, warum es eine zirkuläre Abhängigkeit erkennt.

Der einfachste Weg, um die zirkuläre Abhängigkeit zu vermeiden, ist, dass Ihre Registrierung nicht auf sich selbst angewiesen ist. Dies ist, was Sie tun, indem Sie einen Namen ILog auflösen und das ist die Lösung, die ich empfehle.

In Ihrem Fall können Sie auch direkt das Protokoll root verwenden, ohne sie zu lösen:

containerBuilder.RegisterInstance(rootLog).As<ILog>(); 
containerBuilder.Register(ctx => { 
    return new PrependStringLog(rootLog, "request: "); 
}).InstancePerRequest(); 
+0

In meinem Kopf, mit unterschiedlicher Lebensdauer Tive genug war, um die Auflösung Mechanismus zu erleichtern. Immerhin hat der per-request-Bereich einen übergeordneten Bereich, in dem es bereits eine perfekt gültige ILog-Instanz gibt, und das wäre eine zirkuläre Abhängigkeit. Davon abgesehen verstehe ich Ihre Argumentation, ich werde weiterbenannte Instanzen verwenden. – Raine