我有一个Web控制器,比如EmployeeController,我们使用Autofac注册它。现在,我们使用相同的名称和路径创建另一个控制器,但功能不同。当我们尝试使用Autofac注册这个新的EmployeeController (即插件)时,我们会得到一个异常,如
发现与名为
EmployeeController的控制器匹配的多个类型。
我的目标是成功地注入第二个控制器,并用它覆盖第一个控制器的功能。
项目A->核心项目
namespace Main.API
{
public class EmployeeController : ApiController
{
// Some Logic
}
}项目B->插件项目
稍后,使用者希望覆盖具有相同控制器名称的雇员控制器。
namespace Plugin.API
{
public class EmployeeController : ApiController
{
// Some Logic
}
}Autofac
// assemblies contains Main.API.dll & Plugin.API.dll
builder.RegisterApiControllers(assemblies.ToArray()).InstancePerRequest();发布于 2017-07-18 09:40:56
为了实现您想要的东西,我将使用AOP概念,这将使它更容易实现和更强大。
https://github.com/castleproject/Core/blob/master/docs/dynamicproxy.md项目为.net提供了AOP概念,可以与Autofac.Extras.DynamicProxy2 nuget包一起使用Autofac。
您的主项目中只有一个EmployeeController。
namespace Main.API
{
public class EmployeeController : ApiController
{
public virtual String Get(Int32 id)
{
// Some Logic
}
}
}以及插件项目中的各种IInterceptor:
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";
}
}
}然后注册如下:
builder.RegisterApiControllers(assemblies.ToArray())
.InstancePerRequest()
.EnableClassInterceptors();
builder.RegisterAssemblyTypes(assemblies.ToArray())
.As<IInterceptor>(); 有关更多信息,请参见型拦截器
发布于 2017-08-21 11:23:10
使用下面的代码片段,您可以覆盖插件控制器的相同名称。
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;
}
}https://stackoverflow.com/questions/45141144
复制相似问题