使用场景?

很多时候, 我们定义一个功能, 当我们要对这个功能进行扩展的时候, 按照常规的思路, 我们一般都是利用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. 静态时序分析SAT

    1.   背景 静态时序分析的前提就是设计者先提出要求,然后时序分析工具才会根据特定的时序模型进行分析,给出正确是时序报告. 进行静态时序分析,主要目的就是为了提高系统工作主频以及增加系统的稳定性.对 ...

  2. legend---四、菜鸟教程css3里面有教你炫酷的按钮怎么做

    legend---四.菜鸟教程css3里面有教你炫酷的按钮怎么做 一.总结 一句话总结:想学,总是有很多资料的 1. 自动居中是 margin:100px 0px;么? 自动居中是margin:100 ...

  3. Zuul 2 : The Netflix Journey to Asynchronous, Non-Blocking Systems--转

    原文地址:http://techblog.netflix.com/2016/09/zuul-2-netflix-journey-to-asynchronous.html We recently mad ...

  4. codeforces 589A Email Aliases(map)

    Description Polycarp has quite recently learned about email aliases. Of course, he used to suspect t ...

  5. 解决电信或网通的DNS劫持

    大家有没有碰到访问一些不存在域名或者网站时,浏览器本应显示一个网址不存在之类的信息,但是因为现在很多ISP做了DNS劫持将不存在的域名或网址重定向到ISP的广告页面,烦人的狠.其实tomato可以解决 ...

  6. 微信、QQ中app的下载问题

    最近在做一个项目,有一项功能是从微信中的分享页或者产品推广页面中下载app:在微信中直接下载app时微信是“拒绝”的,所以一般的做法是点击下载按钮弹出遮罩层,提示在浏览器中打开,然后进入外部浏览器,再 ...

  7. Android 第三方分享中遇到的问题以及解决方案

    本文来自http://blog.csdn.net/liuxian13183/ ,引用必须注明出处! 第三方登录和分享过程中难免遇到各种纠结的问题,下面将我遇到的分享给大家. 先说第三方登录 1.首先要 ...

  8. Reuse Is About People and Education, Not Just Architecture

     Reuse Is About People and Education, Not Just Architecture Jeremy Meyer you MigHT AdopT THE AppRoA ...

  9. Redis命令学习-Transaction(事务)

    DISCARD ​DISCARD :取消事务,放弃运行事务块内的全部代码.假设在使用WATCH命令监视某个key.则取消监视,等同于UNWATCH. ​返回值:总是返回ok.    ​     ​ ...

  10. 深入理解 GRE tunnel

    深入理解 GRE tunnel 时间 2012-11-08 19:05:22  A Geek's Page 原文  http://wangcong.org/blog/archives/2149 主题  ...