在前文的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

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

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

  1. 自己实现简单的AOP(四)自动初始化代理对象

    前面三篇随笔,已经完成了AOP的核心功能,但 代理对象的初始化还是有些麻烦,本文将解决该问题. Demo 片段如下: public class HomeController : Controller ...

  2. 一个简单的MariaDB认证插件demo

    代码地址如下:http://www.demodashi.com/demo/13076.html 一.前言 众所周知(其实可能很多人不知道)MariaDB支持插件认证.在MariaDB中新建用户,常见的 ...

  3. 自己实现简单的AOP(二)引入Attribute 为方法指定增强对象

    话续前文 : 自己实现简单的AOP(一)简介 在前一篇文章中,对AOP的实现方式做了一个简单介绍.接下来,引入Attribute 为方法指定增强对象,由此实现一个简单的AOP. 注意:指定的是增强对象 ...

  4. socket.io简单说明及在线抽奖demo

    socket.io简单说明及在线抽奖demo socket.io 简介 Socket.IO可以实现实时双向的基于事件的通信. 它适用于各种平台,浏览器或设备,也同样注重可靠性和速度. socket.i ...

  5. 如何使用AEditor制作一个简单的H5交互页demo

    转载自:http://www.alloyteam.com/2015/06/h5-jiao-hu-ye-bian-ji-qi-aeditor-jie-shao/ 本教程演示如何使用AEditor制作一个 ...

  6. 从头认识Spring-3.8 简单的AOP日志实现(注解版)-扩展添加检查订单功能,以便记录并检測输入的參数

    这一章节我们讨论一下扩展添加检查订单功能,以便记录并检測输入的參数. 1.domain 蛋糕类: package com.raylee.my_new_spring.my_new_spring.ch03 ...

  7. aop学习总结二------使用cglib动态代理简单实现aop功能

    aop学习总结二------使用cglib动态代理简单实现aop功能 模拟业务需求: 1.拦截所有业务方法 2.判断用户是否有权限,有权限就允许用户执行业务方法,无权限不允许用户执行业务方法 (判断是 ...

  8. 从头认识Spring-3.1 简单的AOP日志实现-某方法之前的前后记录日志

    这一章节我们引入简单的AOP日志实现. 1.domain 蛋糕类: package com.raylee.my_new_spring.my_new_spring.ch03.topic_1_1; pub ...

  9. 从头认识Spring-3.4 简单的AOP日志实现-扩展添加检查订单功能,以便记录并检測输入的參数

    这一章节我们再上一个章节的基础上加上一个检查订单功能 1.domain 蛋糕类: package com.raylee.my_new_spring.my_new_spring.ch03.topic_1 ...

随机推荐

  1. matlab size、numel、length、fix函数的使用,补充nargin

    size():获取矩阵的行数和列数 (1)s=size(A), 当只有一个输出参数时,返回一个行向量,该行向量的第一个元素时矩阵的行数,第二个元素是矩阵的列数.(2)[r,c]=size(A), 当有 ...

  2. 持续集成及部署利器:Go

    Go是一款先进的持续集成和发布管理系统,由ThoughtWorks开发.(不要和Google的编程语言Go混淆了!)其前身为CruiseControl,是ThoughtWorks在做咨询和交付交付项目 ...

  3. 【Java并发编程实战】-----“J.U.C”:锁,lock

    在java中有两种方法实现锁机制,一种是在前一篇博客中([java7并发编程实战]-----线程同步机制:synchronized)介绍的synchronized,而另一种是比synchronized ...

  4. Linux LVM逻辑卷

    概述 LVM的产生是因为传统的分区一旦分区好后就无法在线扩充空间,也存在一些工具能实现在线扩充空间但是还是会面临数据损坏的风险:传统的分区当分区空间不足时,一般的解决办法是再创建一个更大的分区将原分区 ...

  5. Atitit常见的标准化组织与规范数量jcp ecma iso

    Atitit常见的标准化组织与规范数量jcp ecma iso 1. 常见的标准化组织1 1.1. 重要的基金会apache1 1.2. 美国国家标准学会(American NationalStand ...

  6. CSS系列:CSS中盒子之间的关系

    1. 标准文档流 标准文档流是值在不使用其他的雨排列和定位相关的特殊CSS规则时,各种元素的排列规则. 1.1 块级元素(block level) 块级元素不会排在同一行中,总是以一个块的形式表现出来 ...

  7. 【转】Linux C动态内存泄漏追踪方法

    原文:http://www.cnblogs.com/san-fu-su/p/5737984.html C里面没有垃圾回收机制,有时候你申请了动态内存却忘记释放,这就尴尬了(你的程序扮演了强盗角色,有借 ...

  8. 用jquery.pager.js实现分页

    1.html <link href="/stylesheets/Pager.css" rel="stylesheet" type="text/c ...

  9. VXLAN 概念(Part I) - 每天5分钟玩转 OpenStack(108)

    除了前面讨论的 local, flat, vlan 这几类网络,OpenStack 还支持 vxlan 和 gre 这两种 overlay network. overlay network 是指建立在 ...

  10. android给View设置边框 填充颜色 弧度

    <?xml version="1.0" encoding="utf-8"?> <shape xmlns:android="http: ...