C# Unity依赖注入利用Attribute实现AOP功能

使用场景?

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

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

 

1.准备工作

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

C# Unity依赖注入利用Attribute实现AOP功能_第1张图片

在使用的项目中添加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 = "123123123123"
            };
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[0] as User;
                if (user.Password.Length < 10)
                {
                    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[0] 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 = 1)] //注册校验
        [LogHandlerAttribute(Order = 2)]  //日志处理
        [ExceptionHandlerAttribute(Order = 3)] //遗产处理
        public interface IUserProcessor
        {
            void RegUser(User user);
        }

//PS: 在上面的特性声明中, 每个对应的Order 这个属于排序, 相对于一个行为的执行顺序, 这个内部是Unity的一个实现, 所以我们使用的过程中只需要声明好标量即可。

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

            //声明一个容器
            IUnityContainer container = new UnityContainer();

            //声明UnityContainer并注册IUserProcessor
            container.RegisterType();

            container.AddNewExtension().Configure()
                .SetInterceptorFor(new InterfaceInterceptor());
            IUserProcessor userprocessor = container.Resolve();
            userprocessor.RegUser(user); //调用注册方法。

 

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

C# Unity依赖注入利用Attribute实现AOP功能_第2张图片

 

 

 

小结:

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

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

 

转载于:https://www.cnblogs.com/zh7791/p/7923305.html

你可能感兴趣的:(C# Unity依赖注入利用Attribute实现AOP功能)