2017-07-17 7 views
0

Ich habe einen Web-API-Controller, sagen wir EmployeeController, die wir mit Autofac registrieren. Jetzt erstellen wir einen anderen Controller mit dem gleichen Namen und der gleichen Route, jedoch mit unterschiedlicher Funktionalität. Wenn wir versuchen, diese neue EmployeeController (das heißt Plugin) registrieren mit Autofac, würden wir eine Ausnahme wieWie ein Plugin WebAPI eine bestehende WebAPI überschreiben kann

mehrere Arten gefunden wurden erhalten, die den Controller EmployeeController dem Namen übereinstimmen.

Mein Ziel ist es, den zweiten Controller erfolgreich zu injizieren und damit die Funktionalität des ersten Controllers zu übersteuern.

Projekt A -> Kernprojekt

namespace Main.API 
{ 
    public class EmployeeController : ApiController 
    { 
     // Some Logic 
    }  
} 

Projekt B -> Plug-in-Projekt

Später Verbraucher wollen

Mitarbeiter Controller mit dem gleichen Controller-Namen zu überschreiben
namespace Plugin.API 
{ 
    public class EmployeeController : ApiController 
    { 
     // Some Logic 
    }  
} 

Autofac

// assemblies contains Main.API.dll & Plugin.API.dll 
builder.RegisterApiControllers(assemblies.ToArray()).InstancePerRequest(); 
+0

Ich denke, Sie werden ne benutzerdefinierte Registrierungsquelle dafür arbeiten. http://docs.autofac.org/en/latest/advanced/registration-sources.html – Jehof

Antwort

0

Um das umzusetzen, was Sie wollen, würde ich AOP concept verwenden, die es einfacher zu implementieren und leistungsfähiger machen.

Castle DynamicProxy Projekt bietet AOP-Konzept für .net und kann durch Autofac mit dem Autofac.Extras.DynamicProxy2 nuget Paket verwendet werden.

Sie nur 1 EmployeeController in Ihrem Hauptprojekt

namespace Main.API 
{ 
    public class EmployeeController : ApiController 
    { 
     public virtual String Get(Int32 id) 
     { 
      // Some Logic 
     } 
    }  
} 

und verschiedene IInterceptor in Ihrem Plugin-Projekte haben:

namespace Plugin 
{ 
    public class XEmployeeeControllerInterceptor : IInterceptor 
    { 
     public void Intercept(IInvocation invocation) 
     { 
      if(!invocation.Method.Name == nameof(Core.APi.EmployeeController.Get)) 
      { 
       return; 
      } 
      invocation.Proceed(); 

      // alter return value 
      invocation.ReturnValue = invocation.ReturnValue + "-intercepted"; 
     } 
    } 
} 

Dann wie diese Dinge registrieren:

builder.RegisterApiControllers(assemblies.ToArray()) 
     .InstancePerRequest() 
     .EnableClassInterceptors(); 

builder.RegisterAssemblyTypes(assemblies.ToArray()) 
     .As<IInterceptor>(); 

See Type Interceptors für weitere Informationen

+0

Erstens danke ich Cyril Durand. Lassen Sie mich wissen, wenn es eine Möglichkeit gibt, einfach Typ (EmployeeController) von Main.API ​​DLL ausschließen, während die RegisterApiControllers?. Vor der DI-Registrierung werde ich prüfen, ob es die gleichen Typen zwischen Main und Plugin gibt, wenn es verfügbar ist, möchte ich den Typ von Main ausschließen, dann kann ich automatisch auf denselben Typ von Plugin zugreifen. – user1611257

0

Mit diesem Code-Snippet können Sie den gleichen Namen des Plugin-Controllers überschreiben.

public class CustomHttpControllerSelector : DefaultHttpControllerSelector 
    { 
     private readonly HttpConfiguration _configuration; 
     private readonly Lazy<Dictionary<string, HttpControllerDescriptor>> _controllers; 


    /// <summary> 
    /// custom http controllerselector 
    /// </summary> 
    /// <param name="config"></param> 
    public CustomHttpControllerSelector(HttpConfiguration config) : base(config) 
    { 
     _configuration = config; 
     _controllers = new Lazy<Dictionary<string, HttpControllerDescriptor>>(InitializeControllerDictionary); 
    } 

    /// <summary> 
    /// GetControllerMapping 
    /// </summary> 
    /// <returns></returns> 
    public override IDictionary<string, HttpControllerDescriptor> GetControllerMapping() 
    { 
     return _controllers.Value; 
    } 

    private Dictionary<string, HttpControllerDescriptor> InitializeControllerDictionary() 
    { 
     var controllers = new Dictionary<string, HttpControllerDescriptor>(StringComparer.OrdinalIgnoreCase); 

     IAssembliesResolver assembliesResolver = _configuration.Services.GetAssembliesResolver(); 
     IHttpControllerTypeResolver controllersResolver = _configuration.Services.GetHttpControllerTypeResolver(); 
     ICollection<Type> controllerTypes = controllersResolver.GetControllerTypes(assembliesResolver); 

     foreach (Type t in controllerTypes) 
     { 
      var controllerName = t.Name.Remove(t.Name.Length - DefaultHttpControllerSelector.ControllerSuffix.Length); 

      //Remove Core API Controller and add the Plugin API controller. 
      if (controllers.Keys.Contains(controllerName) && t.Namespace.Contains("Plugin")) 
      { 
       controllers.Remove(controllerName); 
      } 
      if (!controllers.Keys.Contains(controllerName)) 
      { 
       controllers[controllerName] = new HttpControllerDescriptor(_configuration, t.Nam`enter code here`e, t); 
      } 
     } 
     return controllers; 
    } 
}