2016-07-15 4 views
1

In einer Web-API-Anwendung, habe ich zwei Controller, MyAController und MyBController, die jeweils auf IMyService abhängig, aber mit einer anderen Konfiguration:Inject Dienst mit unterschiedlicher Konfiguration in der Steuerung

public class MyAController : ApiController 
{ 
    private readonly IMyService service; 
    public MyAController(IMyService service) 
    { 
     this.service = service; 
    } 
} 

public class MyBController : ApiController 
{ 
    private readonly IMyService service; 
    public MyBController(IMyService service) 
    { 
     this.service = service; 
    } 
} 

public interface IMyService 
{ 
} 

public class MyService : IMyService 
{ 
    private readonly string configuration; 
    public MyService(string configuration) 
    { 
     this.configuration = configuration; 
    } 
} 

Ich habe versucht DryIoc Konfiguration des folgenden übrigens:

private enum ServiceKeyEnum 
{ 
    ServiceA, 
    ServiceB 
} 

container.RegisterInstance("configurationA", serviceKey: "CONFIGURATIONA"); 
container.RegisterInstance("configurationB", serviceKey: "CONFIGURATIONB"); 
container.Register<IMyService, MyService>(Reuse.Singleton, Made.Of(() => new MyService(Arg.Of<string>("CONFIGURATIONA"))), serviceKey: ServiceKeyEnum.ServiceA); 
container.Register<IMyService, MyService>(Reuse.Singleton, Made.Of(() => new MyService(Arg.Of<string>("CONFIGURATIONB"))), serviceKey: ServiceKeyEnum.ServiceB); 

container.Register<MyAController>(Reuse.InResolutionScope, made: Parameters.Of.Details((r, p) => ServiceDetails.IfUnresolvedReturnDefault).Type<IMyService>(serviceKey: ServiceKeyEnum.ServiceA)); 
container.Register<MyBController>(Reuse.InResolutionScope, made: Parameters.Of.Details((r, p) => ServiceDetails.IfUnresolvedReturnDefault).Type<IMyService>(serviceKey: ServiceKeyEnum.ServiceB)); 

und wenn ich versuche, Entschlossenheit zu nennen mit:

var controllerA = container.Resolve<MyAController>(); 
var controllerB = container.Resolve<MyBController>(); 

Ich bekomme zwei Controller, die mit configurationA bzw. configurationB konfiguriert sind. Allerdings, wenn ich versuche, die api rufen Sie ein REST-Call, ich folgende Fehlermeldung erhalten:

An error occurred when trying to create a controller of type 'MyAController'. Make sure that the controller has a parameterless public constructor. 

also denke ich, dass ich den Controller auf eine andere Weise registrieren muß ... aber wie?

Jede Hilfe wäre sehr geschätzt ....

+1

Vielleicht eine dumme Frage, aber haben Sie Web-API für DryIoC konfiguriert? https://www.nuget.org/packages/DryIoc.WebApi/ – Michael

+0

Warum Controller mit Reuse.InResolutionScope anstelle von InWebRequest registriert? Wenn sie direkt aufgelöst werden, macht es sie effektvoll Transient. – dadhi

+0

Ja, WebAPI ist mit container.WithWebApi (GlobalConfiguration.Configuration) konfiguriert; Ich habe sowohl InWebRequest, InResolutionScope, .... ohne Erfolg versucht – smolesen

Antwort

0

Der Fehler wird für Controller durch falsche Setup verursacht. Die DryIoc.WebApi-Erweiterung hat Ihre Controller bereits erkannt und registriert. Sie müssen dies normalerweise nicht selbst tun. Ich werde den Arbeitscode (aus den Fragekommentaren) für Ihre spezifische Einrichtung später bereitstellen. Aber jetzt der Grund hinter dem "parameterless constructor ..": wenn DryIoc fehlschlägt, greift WebAPI auf Activator.CreateInstance für den Controller zurück, der parameterlosen Konstruktor erwartet. Das Fallback maskiert den ursprünglichen DryIoc-Fehler. Um es zu finden, können Sie Setup DryIoc.WebApi Erweiterung als:

container = container.WithWebApi(throwIfUnresolved: type => type.IsController()); 

Die Arbeits Setup für Ihren Fall, die Abhängigkeiten mit Bedingung Register wählen Controller für die Injektion:

container.Register<IMyService, MyService>(Made.Of(
    () => new MyService(Arg.Index<string>(0)), _ => "configurationA"), 
    Reuse.Singleton, 
    setup: Setup.With(condition: r => r.Parent.ImplementationType == typeof(MyAController))); 

container.Register<IMyService, MyService>(Made.Of(
    () => new MyService(Arg.Index<string>(0)), _ => "configurationB"), 
    Reuse.Singleton, 
    setup: Setup.With(condition: r => r.Parent.ImplementationType == typeof(MyBController))); 

Die Hauptsache ist, dass diese Setup erfordert keine spezielle Controller-Registrierung.

Außerdem können Sie die Verwendung von Serviceschlüsseln vermeiden und müssen die Konfigurationszeichenfolgen nicht separat registrieren.

+0

War nicht bewusst, Setup.With Condition, wirklich eine nette Art, damit umzugehen. – smolesen

Verwandte Themen