
监控
AOP vs MVC FilterAttributes vs 拦截器
在软件开发中,我们经常需要处理一些与业务逻辑无关的通用功能,比如日志记录、权限控制、性能监控等。为了提高代码的可重用性和可维护性,我们可以使用一些设计模式和技术来实现这些通用功能。本文将介绍AOP(面向切面编程)和MVC(模型-视图-控制器)框架中的FilterAttributes(过滤器属性)以及拦截器的概念,以及它们在实际开发中的应用。AOP(面向切面编程)AOP是一种编程范式,它将横切关注点(Crosscutting Concerns)与业务逻辑分离。横切关注点是指与业务逻辑无关的功能,如日志记录、事务管理、异常处理等。AOP通过将这些横切关注点独立出来,以切面(Aspect)的形式来实现它们,并将它们应用到业务逻辑的不同位置,从而实现代码的重用和维护性的提高。在ASP.NET Core中,我们可以使用AspectCore框架来实现AOP。下面是一个使用AspectCore框架实现日志记录的例子:csharp[AttributeUsage(AttributeTargets.Method)]public class LogAttribute : ABStractInterceptorAttribute{ public override async Task Invoke(AspectContext context, AspectDelegate next) { Console.WriteLine($"Entering method {context.ServiceMethod.Name}"); awAIt next(context); Console.WriteLine($"Exiting method {context.ServiceMethod.Name}"); }}public interface IService{ [Log] void DoSomething();}public class Service : IService{ public void DoSomething() { Console.WriteLine("Doing something..."); }}public class Program{ public static void MAIn(string[] args) { var service = ProxyGenerator.CreateClassProxy<Service, IService>(); service.DoSomething(); }}在上面的例子中,我们定义了一个名为LogAttribute的切面,它继承自AspectCore框架中的ABStractInterceptorAttribute类,并重写了Invoke方法。在Invoke方法中,我们实现了日志记录的逻辑。然后,我们定义了一个名为IService的接口,并在其中的DoSomething方法上应用了LogAttribute切面。最后,我们通过使用AspectCore框架提供的ProxyGenerator类,来创建一个IService接口的代理对象service,并调用其DoSomething方法。当调用DoSomething方法时,AspectCore框架会自动触发LogAttribute切面中的Invoke方法,从而实现了日志记录的功能。MVC FilterAttributes(过滤器属性)在ASP.NET MVC框架中,我们可以使用FilterAttributes来实现类似于AOP的功能。FilterAttributes是一种特殊的属性,它可以应用到控制器或者动作方法上,用于实现一些通用的功能,如日志记录、权限控制、性能监控等。下面是一个使用FilterAttributes实现日志记录的例子:csharppublic class LogActionFilterAttribute : ActionFilterAttribute{ public override void OnActionExecuting(ActionExecutingContext context) { Console.WriteLine($"Entering action {context.ActionDescriptor.DisplayName}"); } public override void OnActionExecuted(ActionExecutedContext context) { Console.WriteLine($"Exiting action {context.ActionDescriptor.DisplayName}"); }}[LogActionFilter]public class HomeController : Controller{ public IActionResult Index() { Console.WriteLine("Executing action Index"); return View(); }}public class Program{ public static void MAIn(string[] args) { var controller = new HomeController(); var actionContext = new ActionContext(); var executingContext = new ActionExecutingContext(actionContext, new List<IFilterMetadata>(), new Dictionary<string, object>(), controller); var executedContext = new ActionExecutedContext(actionContext, new List<IFilterMetadata>(), controller); var logActionFilter = new LogActionFilterAttribute(); logActionFilter.OnActionExecuting(executingContext); controller.Index(); logActionFilter.OnActionExecuted(executedContext); }}在上面的例子中,我们定义了一个名为LogActionFilterAttribute的FilterAttribute,它继承自ASP.NET MVC框架中的ActionFilterAttribute类,并重写了OnActionExecuting和OnActionExecuted方法。在这两个方法中,我们实现了日志记录的逻辑。然后,我们定义了一个名为HomeController的控制器,并在其上应用了LogActionFilterAttribute过滤器。最后,我们通过手动创建ActionExecutingContext和ActionExecutedContext对象,并调用LogActionFilterAttribute过滤器的OnActionExecuting和OnActionExecuted方法来模拟请求处理过程中的日志记录。拦截器拦截器是一种常见的编程技术,它可以在方法调用前后进行一些额外的处理。拦截器通常是通过创建一个代理对象来实现的,代理对象可以拦截对目标对象方法的调用,并在调用前后执行一些额外的逻辑。下面是一个使用拦截器实现缓存功能的例子:csharppublic interface IService{ string GetData();}public class Service : IService{ public string GetData() { Console.WriteLine("Getting data from Database..."); return "Data from Database"; }}public class CacheInterceptor : IInterceptor{ private readonly IDictionary<string, object> _cache = new Dictionary<string, object>(); public void Intercept(IInvocation invocation) { var cacheKey = $"{invocation.TargetType.FullName}.{invocation.Method.Name}"; if (_cache.ContAInsKey(cacheKey)) { invocation.ReturnValue = _cache[cacheKey]; Console.WriteLine($"Returning cached data for method {cacheKey}"); } else { invocation.Proceed(); _cache[cacheKey] = invocation.ReturnValue; Console.WriteLine($"Caching data for method {cacheKey}"); } }}public class Program{ public static void MAIn(string[] args) { var generator = new ProxyGenerator(); var cacheInterceptor = new CacheInterceptor(); var service = generator.CreateInterfaceProxyWithTarget<IService>(new Service(), cacheInterceptor); var data1 = service.GetData(); var data2 = service.GetData(); }}在上面的例子中,我们定义了一个名为IService的接口和一个名为Service的实现类。然后,我们定义了一个名为CacheInterceptor的拦截器,它实现了Castle.Core框架中的IInterceptor接口,并在Intercept方法中实现了缓存功能的逻辑。最后,我们使用Castle.Core框架提供的ProxyGenerator类,来创建一个IService接口的代理对象service,并同时将Service对象和CacheInterceptor拦截器对象传递给CreateInterfaceProxyWithTarget方法。当调用service的GetData方法时,CacheInterceptor拦截器会拦截这个调用,并根据缓存中的数据,决定是否直接返回缓存的数据,或者执行目标方法并缓存结果。AOP、MVC FilterAttributes和拦截器都是一些常见的技术,用于实现与业务逻辑无关的通用功能。它们可以提高代码的可重用性和可维护性,使开发人员能够更专注于业务逻辑的实现。在实际开发中,我们可以根据具体的需求和技术栈选择合适的技术来解决问题。无论是AOP、MVC FilterAttributes还是拦截器,它们都是非常有用的工具,可以帮助我们实现各种通用功能。Copyright © 2025 IZhiDa.com All Rights Reserved.
知答 版权所有 粤ICP备2023042255号