使用场景?

很多时候, 我们定义一个功能, 当我们要对这个功能进行扩展的时候, 按照常规的思路, 我们一般都是利用OOP的思想, 在原有的功能上进行扩展。

那么有没有一种东西, 可以实现当我们需要扩展这个功能的时候, 在不修改原来的功能代码的情况下实现, 这就是下面要说的到Unity。

1.准备工作

为项目添加NuGet包, 搜索Unity并且安装。

在使用的项目中添加Unity的相关引用

using Microsoft.Practices.Unity.InterceptionExtension;
using Microsoft.Practices.Unity;

2.假设场景

刚才上面说道, Unity可实现在不修改原功能的情况下, 添加额外的扩展功能。在我们的实际开发中, 也可以举个简单的例子。

当我们去做一个用户注册的功能, 最初的版本是完成了基本的注册功能, 后来我们需要扩展了, 给他加上注册校验, 日志处理, 和异常捕捉的几个功能, 那么接下来就演示, 如何用Unity给功能扩展。

3.如何使用

首先, 我们定义好一个最原始的注册功能

        public static void Show()
{
User user = new User()
{
Name = "Eleven",
Password = ""
};
IUserProcessor porcessor = new UserProcessor();
            porcessor.RegUser(user); //简单的用户注册
}
        public interface IUserProcessor
{
void RegUser(User user);
} public class UserProcessor : IUserProcessor//MarshalByRefObject,
{
public void RegUser(User user)
{
Console.WriteLine("注册。");
}
}

接下来, 我们要对这个注册进行扩展了, 添加注册校验, 日志处理, 和异常捕捉的几个功能。

1.先定义3个特性与对应的特性行为实现, 分别是注册, 日志, 和异常。

       public class UserHandlerAttribute : HandlerAttribute  //注册校验
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
ICallHandler handler = new UserHandler() { Order = this.Order };
return handler;
}
} public class LogHandlerAttribute : HandlerAttribute //日志处理
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new LogHandler() { Order = this.Order };
}
} public class ExceptionHandlerAttribute : HandlerAttribute //异常处理
{
public override ICallHandler CreateHandler(IUnityContainer container)
{
return new ExceptionHandler() { Order = this.Order };
}
}

对应的每个特性的实现行为, 分别实现 注册校验, 日志记录, 与 异常处理

        public class UserHandler : ICallHandler  //注册校验的行为
{
public int Order { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
User user = input.Inputs[] as User;
if (user.Password.Length < )
{
return input.CreateExceptionMethodReturn(new Exception("密码长度不能小于10位"));
}
Console.WriteLine("参数检测无误"); IMethodReturn methodReturn = getNext.Invoke().Invoke(input, getNext); return methodReturn;
}
} public class LogHandler : ICallHandler //日志处理的行为
{
public int Order { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
User user = input.Inputs[] as User;
string message = string.Format("RegUser:Username:{0},Password:{1}", user.Name, user.Password);
Console.WriteLine("日志已记录,Message:{0},Ctime:{1}", message, DateTime.Now);
return getNext()(input, getNext);
}
} public class ExceptionHandler : ICallHandler //异常处理的行为
{
public int Order { get; set; }
public IMethodReturn Invoke(IMethodInvocation input, GetNextHandlerDelegate getNext)
{
IMethodReturn methodReturn = getNext()(input, getNext);
if (methodReturn.Exception == null)
{
Console.WriteLine("无异常");
}
else
{
Console.WriteLine("异常:{0}", methodReturn.Exception.Message);
}
return methodReturn;
}
}

按照现在思路, 我们要把这上面写好的几个功能添加在原来的注册功能上, 首先, 我们回到最开始定义接口的地方, 给接口添加我们定义按的3个特性

        [UserHandlerAttribute(Order = )] //注册校验
[LogHandlerAttribute(Order = )] //日志处理
[ExceptionHandlerAttribute(Order = )] //遗产处理
public interface IUserProcessor
{
void RegUser(User user);
} //PS: 在上面的特性声明中, 每个对应的Order 这个属于排序, 相对于一个行为的执行顺序, 这个内部是Unity的一个实现, 所以我们使用的过程中只需要声明好标量即可。

然后, 我们在定义好的注册方法中, 首先声明一个Unity容器UnityContainer , 然后注册其上面的接口 IUserProcessor, 最后调用其接口的注册方法。

            //声明一个容器
IUnityContainer container = new UnityContainer(); //声明UnityContainer并注册IUserProcessor
container.RegisterType<IUserProcessor, UserProcessor>(); container.AddNewExtension<Interception>().Configure<Interception>()
.SetInterceptorFor<IUserProcessor>(new InterfaceInterceptor());
IUserProcessor userprocessor = container.Resolve<IUserProcessor>();
userprocessor.RegUser(user); //调用注册方法。

最后, 我们看一下实际效果, 很轻松的实现了用于注册时候扩展其他更多的行为

小结:

不难发现, Unity的实现 主要以在接口上定义的特性与实现行为  与其内部Unity容器的结合  实现的AOP功能。

因为上面是属于静态的写法, 便于学习, 真正的实现AOP可动态配置, 在IOC里会有详细的介绍。

C# Unity依赖注入利用Attribute实现AOP功能的更多相关文章

  1. Unity 依赖注入之二

    1. 构造子注入 1.1 构造子注入初级代码 container.RegisterType<IMyWork, MyWork>(new InjectionConstructor(new Bo ...

  2. Unity依赖注入使用详解

    写在前面 构造器注入 Dependency属性注入 InjectionMethod方法注入 非泛型注入 标识键 ContainerControlledLifetimeManager单例 Unity注册 ...

  3. WPF PRISM开发入门二(Unity依赖注入容器使用)

    这篇博客将通过一个控制台程序简单了解下PRISM下Unity依赖注入容器的使用.我已经创建了一个例子,通过一个控制台程序进行加减乘除运算,项目当中将输入输出等都用接口封装后,结构如下: 当前代码可以点 ...

  4. C# Unity依赖注入

    简介: 控制反转:我们向IOC容器发出获取一个对象实例的一个请求,IOC容器便把这个对象实例“注入”到我们的手中,在这个过程中你不是一个控制者而是一个请求者,依赖于容器提供给你的资源,控制权落到了容器 ...

  5. Unity 依赖注入

    关于Ioc的框架有很多,比如astle Windsor.Unity.Spring.NET.StructureMap,我们这边使用微软提供的Unity做示例,你可以使用Nuget添加Unity,也可以引 ...

  6. c# Unity依赖注入WebService

    1.IOC与DI简介 IOC全称是Inversion Of Control(控制反转),不是一种技术,只是一种思想,一个重要的面相对象编程的法则,它能知道我们如何设计出松耦合,更优良的程序.传统应用程 ...

  7. 使用Microsoft.Practices.Unity 依赖注入

    Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入 ...

  8. 使用Microsoft.Practices.Unity 依赖注入 转载https://www.cnblogs.com/slardar1978/p/4205394.html

    Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入 ...

  9. DDD实战8_2 利用Unity依赖注入,实现接口对应实现类的可配置

    1.在Util类库下新建DIService类 /// <summary> /// 创建一个类,对应在配置文件中配置的DIServices里面的对象的 key /// </summar ...

随机推荐

  1. 正则表达式 Tricks

    *:0 或 多个 ?:任意一个 [list]:a[xyz]b,a 与 b 之间必须也只能有一个字符,但只能是 x/y/z,也即:axb, ayb, azb [!list]:匹配除 list 中的任意单 ...

  2. string类自定义字符串替换函数replace

    #include <iostream> #include <string> using namespace std; /* *  函数功能:将string字符串中的某些字符替换 ...

  3. 初识activiti

    Activity工作流学习要点 1. 1个插件 在Eclipse中安装Activity插件,让你可以在Eclipse中绘制Activity工作流图 2. 1个引擎 ProcessEngine对象,Ac ...

  4. 关于HTML5和CSS3的几个“新增”

    html5和css3分别是目前最新的web前端编程的标准,加入了新的标准和要求. 1.HTML5新增input输入类型,即type后面的值 文本域 <input type="text& ...

  5. Asp.Net碎知识

    在aspx页面 获取值: UserModel user=new UserModel();实例化 user.Address=context["txtAddress"]; 如果前台不需 ...

  6. 为什么linux驱动中变量或者函数都用static修饰?(知乎问题)

    static定义的全局变量 或函数也只能作用于当前的文件. 世界硬件厂商太多,定义static为了防止变量或 函数 重名,定义成static, 就算不同硬件驱动中的 变更 或函数重名了也没关系 .

  7. Android基于XMPP Smack及Openfire学习笔记(1)

    之前开发的项目中实用到IM聊天功能.可是这块功能公司有专门的IM团队来开发,由他们开发好后.直接接入到我们APP中.我參与写IM相关功能非常地少,所以也一直想学习相关知识 . 眼下Android主要用 ...

  8. [Python] Manipulate Data with Dictionaries in Python

    Dictionaries may be familiar to you as hash maps. In this lesson, you will learn how to create them, ...

  9. HTML5贪吃蛇源代码

    显示效果例如以下:点击这里!       代码下载:点击这里! <script> function show(){  var date = new Date(); //日期对象  var ...

  10. [UnityUI]循环滑动列表

    效果图: 使用的是UGUI和DOTween 当中比較关键的是循环滑动和层次排序: 1.循环滑动:这里先如果显示五张图片.分别标记为0,1,2,3,4,那么当向左滑动时,序列就变为1,2,3,4,0,这 ...