2016-03-23 14 views
1

Ich verwende DryIOC.WebAPI, um meine APIControllers aufzulösen.DryIOC WebAPI-Ausweichcontroller

WebAPI Config ist somit:

public static class WebApiConfig 
{ 
    public static void Register(HttpConfiguration config) 
    { 
     // Web API configuration and services 
     // Configure Web API to use only bearer token authentication. 
     config.SuppressDefaultHostAuthentication(); 
     config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType)); 


     config.EnableCors(); 
     config.MapHttpAttributeRoutes(); 

     config.Routes.MapHttpRoute(
      name: "DefaultApi", 
      routeTemplate: "api/{controller}/{id}", 
      defaults: new { id = RouteParameter.Optional } 
     ); 

     Startup.IocContainer.WithWebApi(config); 
     Startup.IocContainer.RegisterWebApiControllers(config); 
    } 
} 

Seine Arbeiten groß, bis ich eine Zuordnung in der IOC-Container erstellen vergessen. In diesem Fall kann der Dependency-Resolver keine Instanz des APIControllers mit DryIOC erstellen.

Wenn dies passiert, greift es auf den Standard-WebAPI-Resolver zurück, der dann mit dem Fehler "Kein Standardkonstruktor" überbrückt wird.

Dies ist ein unerwünschtes Verhalten für mich. Wenn die DryIOC-Auflösung fehlschlägt, möchte ich, dass die Dinge dort stehenbleiben - kein Fallback auf die Standardimplementierung und keine ungenaue Meldung über keinen Standardkonstruktor. Ich möchte wissen, welche Typen DryIOC nicht beheben kann, damit ich es beheben kann.

Wie kann ich das erreichen?

+0

Sie könnten den Standard-Resolver selbst außer Kraft setzen, bevor Sie ihn an DryIOC übergeben und dort stoppen – Nkosi

+0

Ich habe eine DryIOC-Pull-Anforderung hier gemacht: https://bitbucket.org/dadhi/dryioc/pull-requests/15/changed-the- Auflösung-Verhalten-zu-werfen/diff – reach4thelasers

+0

machen diese Änderung in der DryIOC Rahmen ist ziemlich extrem. Sie sollten die Erweiterbarkeit der Web-API nutzen. Nachdem ich gesehen habe, wie die DryIOC-Quelle den Standard-Resolver ersetzt, anstatt ihn zu umbrechen, bearbeite ich meine Antwort, um zu zeigen, wie Sie den DryIOCResover umhüllen und den gewünschten Fehler werfen können – Nkosi

Antwort

1

Laut Microsoft Dokumentation:

Dependency Injection in ASP.NET Web API 2

Wenn die GetService Methode eine Art nicht lösen können, sollte es null zurück. Wenn die GetServices Methode einen Typ nicht auflösen kann, sollte ein leeres Auflistungsobjekt zurückgeben.

Keine Ausnahmen für unbekannte Typen auslösen.

Implementierungen dieser Schnittstelle sollten an den zugrunde liegenden Dependency-Injektionscontainer delegieren, um den registrierten Dienst für den angeforderten Typ bereitzustellen. Wenn es keine registrierten Dienste des angeforderten Typs sind, erwartet, dass die ASP.NET MVC-Framework Implementierungen von diese Schnittstelle null von GetService zurückzukehren und eine leere Sammlung von GetServices zurückzukehren.

Wenn die Web-API eine Controller-Instanz erstellt, ruft sie zuerst IDependencyResolver.GetService auf, wobei der Steuerungstyp übergeben wird. Sie können diesen Erweiterbarkeitshaken verwenden, um den Controller zu erstellen, der alle Abhängigkeiten auflöst. Wenn GetService null zurückgibt, sucht Web API für einen parameterlosen Konstruktor in der Controller-Klasse.

Sie die Standardeinstellung überschreiben könnte Resolver selbst

public static class ResolverHelper { 
    public static void OverrideResolver(this HttpConfiguration httpConfiguration) { 
     var innerResolver = httpConfiguration.DependencyResolver; 
     var resolver = new MyDryIocDependencyResolver(innerResolver); 
     httpConfiguration.DependencyResolver = resolver; 
    } 
} 

und in Ihrem benutzerdefinierten Resolver nicht, wie immer Sie wollen.

Snippet von MyDryIocDependencyResolver

public class MyDryIocDependencyResolver : IDependencyResolver { 
    IDependencyResolver innerResolver; 

    public MyCustomDependencyResolver(IDependencyResolver innerResolver) { 
     this.innerResolver = innerResolver; 
    } 

    public IDependencyScope BeginScope() { 
     return this; 
    } 

    public object GetService(Type serviceType) { 
     try { 
      return innerResolver.Getservice(serviceType); 
     } catch (Exception ex) { 
      //TODO: Log resolution error 
      return null; 
     } 
    } 

    public IEnumerable<object> GetServices(Type serviceType) { 
     try { 
      return innerResolver.GetServices(serviceType); 
     } catch (Exception ex) { 
      //TODO: Log resolution error 
      return new List<object>(); 
     } 
    } 

    public void Dispose() { 
     // NO-OP 
    } 
} 

In Ihrer Registrierung können Sie dann außer Kraft setzen es

//...other code 
Startup.IocContainer.WithWebApi(config); 
Startup.IocContainer.RegisterWebApiControllers(config); 
config.OverrideResolver(); 
//...other code 

diese Weise, wenn/wenn DryIocDependencyResolver konnte den Diensttyp nicht lösen werden Sie noch wissen, was nicht war entschlossen, fangen Sie es ab und geben Sie die Standardwerte gemäß den vorgeschlagenen Richtlinien ein. Beste aus beiden Welten.

Hoffnung, die

+1

Dies ist in der Tat MS-Empfehlung. Das Problem ist jedoch, dass wir eine detaillierte Ausnahme von der integrierten IoC-Bibliothek verlieren. DryIoc und andere IoCs liefern eine Menge Informationen darüber, was nicht geklärt ist und wie der Zustand des Containers ist. So können Sie das Problem viel schneller lokalisieren. – dadhi

1

Ein anderer Weg hilft, Probleme mit Controller Auflösungen mit allen möglichen Informationen zu überprüfen, ist IContainer.VerifyResolutions Methode zu verwenden.

Zum Beispiel:

var container = new Container().WithWebApi(config); 
var errors = container.VerifyResolutions(); 
Debug.Assert(errors.Length == 0); 

Weitere Details in einem wiki.

Hinweis: Der einzige Haken mit Controllern, dass Strom DryIoc.WebApi Register Controller-Implementierung mit konkreten Steuerungstyp und alle implementierten Typen wie die Diensttypen. Also für eine ungelöste class MyController: ApiController {} Methode VerifyResolutions 3 identische Fehler zurück:

  • eine für MyController
  • eine für ApiController
  • und eine für IHttpController

Sie können zur Verifizierung des Ergebnisses Gruppe errors von Factory.FactoryID zu haben eine kompaktere Ausgabe.