.NET(C#) 面向切面编程(AOP) Castle Windsor

AOP(Aspect Oriented Programming)是面向切面编程,用来在不修改代码的情况下,动态的添加功能,通过预编译方式和运行期动态代理实现程序功能的中统一处理业务逻辑的一种技术,利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。比较常见的场景是:日志记录,错误捕获、性能监控等。本文主介绍Castle Windsor实现AOP方法,以及相关的示例代码。

1、Castle Windsor

Castle最早在2003年诞生于Apache Avalon项目,目的是为了创建一个IOC(控制反转)框架。目前包括四个组件,分别是ActiveRecord(ORM组件),Windsor(IOC组件),DynamicProxy(动态代理组件),MonoRail(Web MVC组件)。

2、安装引用Castle Windsor

1)使用Nuget管理控制台

可以通过打开包管理器控制台(PM)并键入以下语句来安装Castle Windsor:

Install-Package Castle.Windsor

2)使用Nuget图形管理器

使用Nuget的界面的管理器搜索 "Castle.Windsor" => 找到点出点击 "安装"。

3)使用.NET CLI命令安装

> dotnet add TodoApi.csproj package Castle.Windsor

相关文档VS(Visual Studio)中Nuget的使用

2、使用静态代理实现AOP

使用面向对象的方式实现AOP,代码如下,

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication
{
    //一般每个接口或类都写在单独的.cs文件中
    //本示例为了执行查看方便才写在一起
    public class User
    {
        public string UserName { get; set; }
        public string PassWord { get; set; }
    }
    public interface IUserProcessor
    {
        void RegUser(User user);
    }
    public class UserProcessor : IUserProcessor
    {
        public void RegUser(User user)
        {
            Console.WriteLine(" 用户已注册。Name:{0},PassWord:{1} ", user.UserName, user.PassWord);
        }
    }
    //通过定义一个装饰器类实现
    public class UserProcessorDecorator : IUserProcessor
    {
        public IUserProcessor UserProcessor { get; set; }
        public UserProcessorDecorator(IUserProcessor userprocessor)
        {
            UserProcessor = userprocessor;
        }
        public void RegUser(User user)
        {
            PreProceed(user);
            UserProcessor.RegUser(user);
            PostProceed(user);
        }
        public void PreProceed(User user)
        {
            Console.WriteLine(" 方法执行前 ");
        }
        public void PostProceed(User user)
        {
            Console.WriteLine(" 方法执行后 ");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            User user = new User() { UserName = "cjavapy", PassWord = "123456" };
            IUserProcessor userprocessor = new UserProcessorDecorator(new UserProcessor());
            userprocessor.RegUser(user);
            Console.ReadKey();
        }
    }
}

3、使用Castle Windsor DynamicProxy实现AOP

使用Castle Windsor DynamicProxy实现动态代理,代码如下,

using Castle.Core;
using Castle.DynamicProxy;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApplication
{
    //一般每个接口或类都写在单独的.cs文件中
    //本示例为了执行查看方便才写在一起
    public class ProcessorInterceptor : IInterceptor
    {
        public void Intercept(IInvocation invocation)
        {
            try
            {
                if (invocation.Arguments.Length > 0)
                {
                    PreProceed(invocation.Arguments[0] as User);
                }
                invocation.Proceed();
                if (invocation.Arguments.Length > 0)
                {
                    PostProceed(invocation.Arguments[0] as User);
                }
            }
            catch (Exception)
            {
                Console.WriteLine("方法出错调用");
                throw;
            }
        }
        public void PreProceed(User user)
        {
            Console.WriteLine(" 方法执行前:"+user.UserName);
        }
        public void PostProceed(User user)
        {
            Console.WriteLine(" 方法执行后:"+user.UserName);
        }
    }
    public class User
    {
        public string UserName { get; set; }
        public string PassWord { get; set; }
    }
    public interface IUserProcessor
    {
        void RegUser(User user);
    }
    [Interceptor(typeof(ProcessorInterceptor))]
    public class UserProcessor : IUserProcessor
    {
        public void RegUser(User user)
        {
            Console.WriteLine(" 用户已注册。Name:{0},PassWord:{1} ", user.UserName, user.PassWord);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            User user = new User() { UserName = "cjavapy", PassWord = "123456" };
            using (var container = new WindsorContainer())
            {
                // container.Register(
                // Component.For()
                //.ImplementedBy()
                //.Named("ProcessorInterceptor"));
                container.Register(
                Component.For()
               .ImplementedBy()
               );
                //container.Register(Component.For().ImplementedBy().Interceptors(InterceptorReference.ForKey("ProcessorInterceptor")).Anywhere);
                container.Register(Component.For().ImplementedBy());
                var root = container.Resolve();
                root.RegUser(user);
            }
            Console.ReadKey();
        }
    }
}

输出:

 方法执行前:cjavapy
 用户已注册。Name:cjavapy,PassWord:123456
 方法执行后:cjavapy

推荐阅读
cjavapy编程之路首页