自己实现简单的AOP(五)使Demo适应webApi、亦可完成属性自动注入

 

在前文的Demo中,webApi的Controller是不能自动注入的,原因是 IHttpController 和 IController 是通过两个不同的途径进行激活的。

IHttpController的激活是通过 IHttpControllerActivator 接口完成的

复制代码
    // 摘要:
    //     定义 System.Web.Http.Dispatcher.IHttpControllerActivator 所需的方法。
    public interface IHttpControllerActivator
    {
        // 摘要:
        //     创建一个 System.Web.Http.Controllers.IHttpController 对象。
        //
        // 参数:
        //   request:
        //     消息请求。
        //
        //   controllerDescriptor:
        //     HTTP 控制器描述符。
        //
        //   controllerType:
        //     控制器的类型。
        //
        // 返回结果:
        //     System.Web.Http.Controllers.IHttpController 对象。
        IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType);
    }
复制代码

而其默认实现类为:DefaultHttpControllerActivator 

复制代码
  // 摘要:
    //     表示 System.Web.Http.Dispatcher.IHttpControllerActivator 的默认实现。可以通过 System.Web.Http.Services.DependencyResolver
    //     注册不同的实现。我们已针对每个 System.Web.Http.Controllers.HttpControllerDescriptor 实例具有一个
    //     System.Web.Http.Controllers.ApiControllerActionInvoker 实例的情况进行优化,但也支持一个 System.Web.Http.Controllers.ApiControllerActionInvoker
    //     具有多个 System.Web.Http.Controllers.HttpControllerDescriptor 实例的情况。对于后一种情况,查找会略慢一些,因为查找需要遍历
    //     HttpControllerDescriptor.Properties 目录。
    public class DefaultHttpControllerActivator : IHttpControllerActivator
    {
        // 摘要:
        //     初始化 System.Web.Http.Dispatcher.DefaultHttpControllerActivator 类的新实例。
        public DefaultHttpControllerActivator();

        // 摘要:
        //     使用给定 request 创建 controllerType 所指定的 System.Web.Http.Controllers.IHttpController。
        //
        // 参数:
        //   request:
        //     请求消息。
        //
        //   controllerDescriptor:
        //     控制器描述符。
        //
        //   controllerType:
        //     控制器的类型。
        //
        // 返回结果:
        //     类型 controllerType 的实例。
        public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType);
    }
复制代码

 

知道了上述信息,最简单的办法就是继承并重写 DefaultHttpControllerActivator ,但是不巧的是其 Create 不是虚函数,不能重写。咋办法呢?变通一下,动态改变对象的行为——装饰模式。当然这里没必要严格按照装饰模式死板的去应用,完全没必要的。只需要按照装饰原理,将 DefaultHttpControllerActivator 进行装饰,再将装饰对象注册到系统中即可。

比如:

复制代码
        /// <summary>
        /// 用于Web Api
        /// </summary>
        private class MyHttpControllerActivator : IHttpControllerActivator
        {
            private DefaultHttpControllerActivator defaultActivator;

            public MyHttpControllerActivator()
            {
                this.defaultActivator = new DefaultHttpControllerActivator();
            }

            public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
            {
                IHttpController httpController = this.defaultActivator.Create(request, controllerDescriptor, controllerType);

                if (httpController != null)
                {
                    /// 自动装配属性
                    /// <para>为属性对象启用代理,并延迟初始化被代理的对象</para>
                    DelayProxyUtil.AutowiredProperties(httpController);
                }

                return httpController;
            }
        }
复制代码

然后在 应用程序启动的时候进行注册:

// 使AOP适应 WebApi
            GlobalConfiguration.Configuration.Services.Replace(typeof(IHttpControllerActivator), new MyHttpControllerActivator());

 

如此,WebApi中的Controller属性,也会被自动注入了。

 

源码地址:https://files.cnblogs.com/files/08shiyan/AOPDemo.zip

 (暂完,后续补充中...)

posted @   把爱延续  阅读(1003)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· Ollama——大语言模型本地部署的极速利器
· DeepSeek如何颠覆传统软件测试?测试工程师会被淘汰吗?
历史上的今天:
2013-11-26 MYSQL 函数 字符串到整数
点击右上角即可分享
微信分享提示