C# Unity依赖注入利用Attribute实现AOP功能
使用场景?
很多时候, 我们定义一个功能, 当我们要对这个功能进行扩展的时候, 按照常规的思路, 我们一般都是利用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功能的更多相关文章
- Unity 依赖注入之二
1. 构造子注入 1.1 构造子注入初级代码 container.RegisterType<IMyWork, MyWork>(new InjectionConstructor(new Bo ...
- Unity依赖注入使用详解
写在前面 构造器注入 Dependency属性注入 InjectionMethod方法注入 非泛型注入 标识键 ContainerControlledLifetimeManager单例 Unity注册 ...
- WPF PRISM开发入门二(Unity依赖注入容器使用)
这篇博客将通过一个控制台程序简单了解下PRISM下Unity依赖注入容器的使用.我已经创建了一个例子,通过一个控制台程序进行加减乘除运算,项目当中将输入输出等都用接口封装后,结构如下: 当前代码可以点 ...
- C# Unity依赖注入
简介: 控制反转:我们向IOC容器发出获取一个对象实例的一个请求,IOC容器便把这个对象实例“注入”到我们的手中,在这个过程中你不是一个控制者而是一个请求者,依赖于容器提供给你的资源,控制权落到了容器 ...
- Unity 依赖注入
关于Ioc的框架有很多,比如astle Windsor.Unity.Spring.NET.StructureMap,我们这边使用微软提供的Unity做示例,你可以使用Nuget添加Unity,也可以引 ...
- c# Unity依赖注入WebService
1.IOC与DI简介 IOC全称是Inversion Of Control(控制反转),不是一种技术,只是一种思想,一个重要的面相对象编程的法则,它能知道我们如何设计出松耦合,更优良的程序.传统应用程 ...
- 使用Microsoft.Practices.Unity 依赖注入
Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入 ...
- 使用Microsoft.Practices.Unity 依赖注入 转载https://www.cnblogs.com/slardar1978/p/4205394.html
Unity是微软Patterns & Practices团队所开发的一个轻量级的,并且可扩展的依赖注入(Dependency Injection)容器,它支持常用的三种依赖注入方式:构造器注入 ...
- DDD实战8_2 利用Unity依赖注入,实现接口对应实现类的可配置
1.在Util类库下新建DIService类 /// <summary> /// 创建一个类,对应在配置文件中配置的DIServices里面的对象的 key /// </summar ...
随机推荐
- C++刷题——2802: 推断字符串是否为回文
Description 编敲代码,推断输入的一个字符串是否为回文. 若是则输出"Yes".否则输出"No". 所谓回文是指順读和倒读都是一样的字符串. Inpu ...
- BZOJ5106: [CodePlus2017]汀博尔
[传送门:BZOJ5106] 简要题意: 给出n棵树,初始高度为h[i],每棵树每个月长高a[i] 现有一个客户,需要至少s长的总木材,而且每次截取的木材必须是一整颗树而且高度大于等于L 求出最少的月 ...
- JNI学习积累之二 ---- 数据类型映射、域描述符说明
本文原创,转载请注明出处:http://blog.csdn.NET/qinjuning 在Java存在两种数据类型: 基本类型 和 引用类型 ,大家都懂的 . 在JNI的世界里也存在类似的数据类型,与 ...
- axure母版使用实例之百度门户
1.首先构建页面基本结构 2.新建母板 3.将母板应用于各个页面 4.在母板中隐藏聚焦背景及下拉二级菜单 5.在母板中添加事件:打开相应界面.显示/隐藏二级菜单 5.设置页面加载效果:给点击的一级菜单 ...
- jython awt demo
jython awt demo : """\ Create a panel showing all of the colors defined in the pawt.c ...
- springMVC No mapping found for HTTP request with URI
转载自:http://blog.sina.com.cn/s/blog_534f69a00101332u.html 1.问题: No mapping found for HTTP request wit ...
- 简述SQL with(unlock)与with(readpast)
所有Select加 With (NoLock)解决阻塞死锁,在查询语句中使用 NOLOCK 和 READPAST 处理一个数据库死锁的异常时候,其中一个建议就是使用 NOLOCK 或者 READPAS ...
- PHP获取一周后的时间戳
echo strtotime("now");//相当于将英文单词now直接等于现在的日期和时间,并把这个日期时间转化为unix时间戳.这个效果跟echo time();一样. ec ...
- 【Codeforces Round #460 (Div. 2) A】 Supermarket
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] 就是让你求m*(ai/bb)的最小值 [代码] #include <bits/stdc++.h> #define dou ...
- FZU 1968 Twinkling lights III
Twinkling lights III Time Limit: 8000ms Memory Limit: 131072KB This problem will be judged on FZU. O ...