首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何允许插件webAPI覆盖现有的webAPI

如何允许插件webAPI覆盖现有的webAPI
EN

Stack Overflow用户
提问于 2017-07-17 09:57:04
回答 2查看 561关注 0票数 0

我有一个Web控制器,比如EmployeeController,我们使用Autofac注册它。现在,我们使用相同的名称和路径创建另一个控制器,但功能不同。当我们尝试使用Autofac注册这个新的EmployeeController (即插件)时,我们会得到一个异常,如

发现与名为EmployeeController的控制器匹配的多个类型。

我的目标是成功地注入第二个控制器,并用它覆盖第一个控制器的功能。

项目A->核心项目

代码语言:javascript
复制
namespace Main.API
{
    public class EmployeeController : ApiController
    {
        // Some Logic
    }    
}

项目B->插件项目

稍后,使用者希望覆盖具有相同控制器名称的雇员控制器。

代码语言:javascript
复制
namespace Plugin.API
{
    public class EmployeeController : ApiController
    {
        // Some Logic
    }    
}

Autofac

代码语言:javascript
复制
// assemblies contains Main.API.dll & Plugin.API.dll
builder.RegisterApiControllers(assemblies.ToArray()).InstancePerRequest();
EN

回答 2

Stack Overflow用户

发布于 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

代码语言:javascript
复制
namespace Main.API
{
    public class EmployeeController : ApiController
    {
        public virtual String Get(Int32 id)
        {
           // Some Logic
        }
    }    
}

以及插件项目中的各种IInterceptor

代码语言:javascript
复制
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";
        }
    }
}

然后注册如下:

代码语言:javascript
复制
builder.RegisterApiControllers(assemblies.ToArray())
       .InstancePerRequest()
       .EnableClassInterceptors();

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

有关更多信息,请参见型拦截器

票数 0
EN

Stack Overflow用户

发布于 2017-08-21 11:23:10

使用下面的代码片段,您可以覆盖插件控制器的相同名称。

代码语言:javascript
复制
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;
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45141144

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档