zoukankan      html  css  js  c++  java
  • 自己实现简单的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属性,也会被自动注入了。

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

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

  • 相关阅读:
    EMIF接口的寻址问题
    C6000系类的内联函数
    C6000代码层面优化(一)
    RHCE学习笔记
    找出并关闭Ruby On Rails进程.
    Rails4添加bootstrap支持
    如何删除gnome3面板上的图标?
    出现 ruby cannot load such file -- zlib 问题的解决方法
    Debian安装软件时提示插入光盘
    Debian7桌面屏蔽图标和右键菜单的解决方法。
  • 原文地址:https://www.cnblogs.com/08shiyan/p/4997463.html
Copyright © 2011-2022 走看看