ASP.NET Core MVC 项目 Autofac 支持 AOP

目录

一:Autofac支持AOP

二:Autofac支持AOP的多种方式

一:类扩展

二:接口扩展

三:类扩展和接口扩展的区别

三:Autofac支持AOP扩展日志记录功能

四:Autofac支持AOP扩展缓存功能

五:Autofac支持AOP扩展IInterceptorSelector


一:Autofac支持AOP

当前项目右键管理Nuget包引入:Castle.core

扩展CusotmInterceptor类

using Castle.DynamicProxy;

namespace Study_ASP.Net_Core_MVC.Services
{
    public class CusotmInterceptor : IInterceptor
    {
        /// <summary>
        /// 切入者逻辑
        /// </summary>
        /// <param name="invocation"></param>
        public void Intercept(IInvocation invocation)
        {
            //方法之前的逻辑
            Console.WriteLine("Begore");
            //执行真实的方法
            invocation.Proceed();
            //方法之后的逻辑
            Console.WriteLine("After");
        }
    }
}

修改关键类ApplePhone

using Autofac.Extras.DynamicProxy;
using Study_ASP.NET_Core_MVC.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Study_ASP.Net_Core_MVC.Services
{
    /// <summary>
    /// 标识特性支持AOP
    /// </summary>
    [Intercept(typeof(CusotmInterceptor))]
    public class ApplePhone : IPhone
    {
        public IMicroPhone MicroPhone { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public IHeadPhone HeadPhone { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public ApplePhone()
        {
            Console.WriteLine("{0}无参构造函数", this.GetType().Name);
        }
        public ApplePhone(IHeadPhone headPhone)
        {
            Console.WriteLine("{0}有参构造函数:{1}", this.GetType().Name,headPhone);
        }

        /// <summary>
        /// 虚方法
        /// 打电话方法
        /// </summary>
        public virtual void Call()
        {
            Console.WriteLine("{0}打电话", this.GetType().Name);
        }
        /// <summary>
        /// 发短信方法
        /// </summary>
        public void Text()
        {
            Console.WriteLine("{0}发短信", this.GetType().Name);
        }
        /// <summary>
        /// 显示当前时间信息
        /// </summary>
        /// <param name="msgInfo">时间信息</param>
        /// <returns></returns>
        public string ShowTime(string timeInfo)
        {
            Console.WriteLine("显示时间:{0}", timeInfo);
            return $"当前时间:{timeInfo}";
        }
    }
}

修改Program.cs文件

using Autofac;
using Autofac.Extensions.DependencyInjection;
using Autofac.Extras.DynamicProxy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Study_ASP.Net_Core_MVC.Services;
using Study_ASP.NET_Core_MVC.Interfaces;
using Study_ASP.NET_Core_MVC.Models;

//表示整个应用程序,调用CreateBuilder方法创建一个WebApplicationBuilder对象。
var builder = WebApplication.CreateBuilder(args);
//向管道容器添加注册中间件
//添加注册控制器视图中间件
builder.Services.AddControllersWithViews();
//添加注册Session中间件
builder.Services.AddSession();

//添加注册Autofac中间件
//通过工厂替换整合Autofac
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
    //注册服务
    containerBuilder.RegisterType<MicroPhone>().As<IMicroPhone>();
    containerBuilder.RegisterType<HeadPhone>().As<IHeadPhone>();
    //支持AAOP扩展
    containerBuilder.RegisterType<ApplePhone>().As<IPhone>().EnableClassInterceptors();
    //注册切入逻辑
    containerBuilder.RegisterType<CusotmInterceptor>();
    //注册控制器和抽象关系
    var controllerBaseType = typeof(ControllerBase);
    //支持属性注入到ControllerBase中
    containerBuilder.RegisterAssemblyTypes(typeof(Program).Assembly).Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType).PropertiesAutowired(new CusotmPropertySelector());
});
//添加注册控制器属性注入
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());

//配置管道容器中间件,构造WebApplication实例
var app = builder.Build();
//判断是否是开发模式
if (!app.Environment.IsDevelopment())
{
    //向管道中添加中间件,该中间件将捕获异常、记录异常、重置请求路径并重新执行请求。
    app.UseExceptionHandler("/Shared/Error");
    //向管道中添加用于使用HSTS的中间件,该中间件添加了Strict Transport Security标头。默认值为30天
    app.UseHsts();
}
//向管道添加Session中间件
app.UseSession();
//向管道添加用于将HTTP请求重定向到HTTPS的中间件。
app.UseHttpsRedirection();
//向管道添加为当前请求路径启用静态文件服务
app.UseStaticFiles();
//向管道添加路由配置中间件
app.UseRouting();
//向管道添加鉴权中间件
app.UseAuthentication();
//向管道添加授权中间件
app.UseAuthorization();
//向管道添加默认路由中间件
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
//向管道添加启动应用程序中间件
app.Run();

修改控制器文件

using Autofac;
using Microsoft.AspNetCore.Mvc;
using Study_ASP.Net_Core_MVC.Services;
using Study_ASP.NET_Core_MVC.Interfaces;
using Study_ASP.NET_Core_MVC.Models;
using System.Diagnostics;

namespace Study_ASP.NET_Core_MVC.Controllers
{
    public class HomeController : Controller
    {
        /// <summary>
        /// 定义构造函数
        /// </summary>
        private readonly ILogger<HomeController> _logger;
        private IPhone iPhone;
        /// <summary>
        /// 初始化构造函数
        /// </summary>
        /// <param name="logger">控制器构造函数</param>
        /// <param name="serviceProvider">服务构造函数</param>
        /// <param name="componentContext">上下文构造函数</param>
        /// <param name="iPhone">自定义构造函数</param>
        public HomeController(ILogger<HomeController> logger, IServiceProvider serviceProvider, IComponentContext componentContext, IPhone iPhone)
        {
            //通过调试查看获取的数据
            _logger = logger;
            this.iPhone = iPhone;
        }
        /// <summary>
        /// Get请求
        /// Home控制器
        /// Index方法
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult Index()
        {
            //调用发短信方法
            iPhone.Text();
            //调用打电话方法
            iPhone.Call();
            //电泳显示实践方法
            ViewBag.ShowTime = iPhone.ShowTime(DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"));
            return View();
        }
    }
}

二:Autofac支持AOP的多种方式

一:类扩展

扩展CusotmInterceptor类

using Castle.DynamicProxy;

namespace Study_ASP.Net_Core_MVC.Services
{
    public class CusotmInterceptor : IInterceptor
    {
        /// <summary>
        /// 切入者逻辑
        /// </summary>
        /// <param name="invocation"></param>
        public void Intercept(IInvocation invocation)
        {
            //方法之前的逻辑
            Console.WriteLine("Begore");
            //执行真实的方法
            invocation.Proceed();
            //方法之后的逻辑
            Console.WriteLine("After");
        }
    }
}

修改关键类ApplePhone

using Autofac.Extras.DynamicProxy;
using Study_ASP.NET_Core_MVC.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Study_ASP.Net_Core_MVC.Services
{
    /// <summary>
    /// 标识特性支持AOP
    /// </summary>
    [Intercept(typeof(CusotmInterceptor))]
    public class ApplePhone : IPhone
    {
        public IMicroPhone MicroPhone { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public IHeadPhone HeadPhone { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public ApplePhone()
        {
            Console.WriteLine("{0}无参构造函数", this.GetType().Name);
        }
        public ApplePhone(IHeadPhone headPhone)
        {
            Console.WriteLine("{0}有参构造函数:{1}", this.GetType().Name,headPhone);
        }

        /// <summary>
        /// 虚方法
        /// 打电话方法
        /// </summary>
        public virtual void Call()
        {
            Console.WriteLine("{0}打电话", this.GetType().Name);
        }
        /// <summary>
        /// 发短信方法
        /// </summary>
        public void Text()
        {
            Console.WriteLine("{0}发短信", this.GetType().Name);
        }
        /// <summary>
        /// 显示当前时间信息
        /// </summary>
        /// <param name="msgInfo">时间信息</param>
        /// <returns></returns>
        public string ShowTime(string timeInfo)
        {
            Console.WriteLine("显示时间:{0}", timeInfo);
            return $"当前时间:{timeInfo}";
        }
    }
}

修改Program.cs文件

using Autofac;
using Autofac.Extensions.DependencyInjection;
using Autofac.Extras.DynamicProxy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Study_ASP.Net_Core_MVC.Services;
using Study_ASP.NET_Core_MVC.Interfaces;
using Study_ASP.NET_Core_MVC.Models;

//表示整个应用程序,调用CreateBuilder方法创建一个WebApplicationBuilder对象。
var builder = WebApplication.CreateBuilder(args);
//向管道容器添加注册中间件
//添加注册控制器视图中间件
builder.Services.AddControllersWithViews();
//添加注册Session中间件
builder.Services.AddSession();

//添加注册Autofac中间件
//通过工厂替换整合Autofac
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
    //注册服务
    containerBuilder.RegisterType<MicroPhone>().As<IMicroPhone>();
    containerBuilder.RegisterType<HeadPhone>().As<IHeadPhone>();
    //支持AAOP扩展--类扩展
    containerBuilder.RegisterType<ApplePhone>().As<IPhone>().EnableClassInterceptors();
    //注册切入逻辑
    containerBuilder.RegisterType<CusotmInterceptor>();
    //注册控制器和抽象关系
    var controllerBaseType = typeof(ControllerBase);
    //支持属性注入到ControllerBase中
    containerBuilder.RegisterAssemblyTypes(typeof(Program).Assembly).Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType).PropertiesAutowired(new CusotmPropertySelector());
});
//添加注册控制器属性注入
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());

//配置管道容器中间件,构造WebApplication实例
var app = builder.Build();
//判断是否是开发模式
if (!app.Environment.IsDevelopment())
{
    //向管道中添加中间件,该中间件将捕获异常、记录异常、重置请求路径并重新执行请求。
    app.UseExceptionHandler("/Shared/Error");
    //向管道中添加用于使用HSTS的中间件,该中间件添加了Strict Transport Security标头。默认值为30天
    app.UseHsts();
}
//向管道添加Session中间件
app.UseSession();
//向管道添加用于将HTTP请求重定向到HTTPS的中间件。
app.UseHttpsRedirection();
//向管道添加为当前请求路径启用静态文件服务
app.UseStaticFiles();
//向管道添加路由配置中间件
app.UseRouting();
//向管道添加鉴权中间件
app.UseAuthentication();
//向管道添加授权中间件
app.UseAuthorization();
//向管道添加默认路由中间件
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
//向管道添加启动应用程序中间件
app.Run();

修改控制器文件

using Autofac;
using Microsoft.AspNetCore.Mvc;
using Study_ASP.Net_Core_MVC.Services;
using Study_ASP.NET_Core_MVC.Interfaces;
using Study_ASP.NET_Core_MVC.Models;
using System.Diagnostics;

namespace Study_ASP.NET_Core_MVC.Controllers
{
    public class HomeController : Controller
    {
        /// <summary>
        /// 定义构造函数
        /// </summary>
        private readonly ILogger<HomeController> _logger;
        private IPhone iPhone;
        /// <summary>
        /// 初始化构造函数
        /// </summary>
        /// <param name="logger">控制器构造函数</param>
        /// <param name="serviceProvider">服务构造函数</param>
        /// <param name="componentContext">上下文构造函数</param>
        /// <param name="iPhone">自定义构造函数</param>
        public HomeController(ILogger<HomeController> logger, IServiceProvider serviceProvider, IComponentContext componentContext, IPhone iPhone)
        {
            //通过调试查看获取的数据
            _logger = logger;
            this.iPhone = iPhone;
        }
        /// <summary>
        /// Get请求
        /// Home控制器
        /// Index方法
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult Index()
        {
            //调用发短信方法
            iPhone.Text();
            //调用打电话方法
            iPhone.Call();
            //显示时间方法
            ViewBag.ShowTime = iPhone.ShowTime(DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"));
            return View();
        }
    }
}

二:接口扩展

扩展CusotmInterceptor类

using Castle.DynamicProxy;

namespace Study_ASP.Net_Core_MVC.Services
{
    public class CusotmInterceptor : IInterceptor
    {
        /// <summary>
        /// 切入者逻辑
        /// </summary>
        /// <param name="invocation"></param>
        public void Intercept(IInvocation invocation)
        {
            //方法之前的逻辑
            Console.WriteLine("Begore");
            //执行真实的方法
            invocation.Proceed();
            //方法之后的逻辑
            Console.WriteLine("After");
        }
    }
}

修改关键类IPhone

using Autofac.Extras.DynamicProxy;
using DocumentFormat.OpenXml.Drawing.Charts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Study_ASP.NET_Core_MVC.Interfaces
{
    /// <summary>
    /// 标识特性支持AOP
    /// </summary>
    [Intercept(typeof(CusotmInterceptor))]
    public interface IPhone
    {
        IMicroPhone MicroPhone { get; set; }
        IHeadPhone HeadPhone { get; set; }
        /// <summary>
        /// 打电话方法
        /// </summary>
        void Call();
        /// <summary>
        /// 发短信方法
        /// </summary>
        void Text();
        /// <summary>
        /// 显示当前时间信息
        /// </summary>
        /// <param name="msgInfo">时间信息</param>
        /// <returns></returns>
        string ShowTime(string timeInfo);
    }
    public interface IMicroPhone { }
    public interface IHeadPhone { }
}

修改Program.cs文件

using Autofac;
using Autofac.Extensions.DependencyInjection;
using Autofac.Extras.DynamicProxy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Study_ASP.Net_Core_MVC.Services;
using Study_ASP.NET_Core_MVC.Interfaces;
using Study_ASP.NET_Core_MVC.Models;

//表示整个应用程序,调用CreateBuilder方法创建一个WebApplicationBuilder对象。
var builder = WebApplication.CreateBuilder(args);
//向管道容器添加注册中间件
//添加注册控制器视图中间件
builder.Services.AddControllersWithViews();
//添加注册Session中间件
builder.Services.AddSession();

//添加注册Autofac中间件
//通过工厂替换整合Autofac
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
    //注册服务
    containerBuilder.RegisterType<MicroPhone>().As<IMicroPhone>();
    containerBuilder.RegisterType<HeadPhone>().As<IHeadPhone>();
    //支持AAOP扩展--接口扩展
    containerBuilder.RegisterType<ApplePhone>().As<IPhone>().EnableInterfaceInterceptors();
    //注册切入逻辑
    containerBuilder.RegisterType<CusotmInterceptor>();
    //注册控制器和抽象关系
    var controllerBaseType = typeof(ControllerBase);
    //支持属性注入到ControllerBase中
    containerBuilder.RegisterAssemblyTypes(typeof(Program).Assembly).Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType).PropertiesAutowired(new CusotmPropertySelector());
});
//添加注册控制器属性注入
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());

//配置管道容器中间件,构造WebApplication实例
var app = builder.Build();
//判断是否是开发模式
if (!app.Environment.IsDevelopment())
{
    //向管道中添加中间件,该中间件将捕获异常、记录异常、重置请求路径并重新执行请求。
    app.UseExceptionHandler("/Shared/Error");
    //向管道中添加用于使用HSTS的中间件,该中间件添加了Strict Transport Security标头。默认值为30天
    app.UseHsts();
}
//向管道添加Session中间件
app.UseSession();
//向管道添加用于将HTTP请求重定向到HTTPS的中间件。
app.UseHttpsRedirection();
//向管道添加为当前请求路径启用静态文件服务
app.UseStaticFiles();
//向管道添加路由配置中间件
app.UseRouting();
//向管道添加鉴权中间件
app.UseAuthentication();
//向管道添加授权中间件
app.UseAuthorization();
//向管道添加默认路由中间件
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
//向管道添加启动应用程序中间件
app.Run();

修改控制器文件

using Autofac;
using Microsoft.AspNetCore.Mvc;
using Study_ASP.Net_Core_MVC.Services;
using Study_ASP.NET_Core_MVC.Interfaces;
using Study_ASP.NET_Core_MVC.Models;
using System.Diagnostics;

namespace Study_ASP.NET_Core_MVC.Controllers
{
    public class HomeController : Controller
    {
        /// <summary>
        /// 定义构造函数
        /// </summary>
        private readonly ILogger<HomeController> _logger;
        private IPhone iPhone;
        /// <summary>
        /// 初始化构造函数
        /// </summary>
        /// <param name="logger">控制器构造函数</param>
        /// <param name="serviceProvider">服务构造函数</param>
        /// <param name="componentContext">上下文构造函数</param>
        /// <param name="iPhone">自定义构造函数</param>
        public HomeController(ILogger<HomeController> logger, IServiceProvider serviceProvider, IComponentContext componentContext, IPhone iPhone)
        {
            //通过调试查看获取的数据
            _logger = logger;
            this.iPhone = iPhone;
        }
        /// <summary>
        /// Get请求
        /// Home控制器
        /// Index方法
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult Index()
        {
            //调用发短信方法
            iPhone.Text();
            //调用打电话方法
            iPhone.Call();
            //电泳显示实践方法
            ViewBag.ShowTime = iPhone.ShowTime(DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"));
            return View();
        }
    }
}

三:类扩展和接口扩展的区别

通过EnableClassInterceptors类扩展时:

  1. 需要将Intercept标记到具体类上
  2. 只有在这个具体类上,标记了虚方法,虚方法才可以进入到IInterceptor中,来支持AOP扩展。

通过EnableInterfaceInterceptors接口扩展时:

  1. 需要将Intercept标记到抽象类上
  2. 只要是实现了这个接口,无论是否是虚方法,都可以进入到IInterceptor中,来支持AOP扩展。

三:Autofac支持AOP扩展日志记录功能

当前项目右键管理Nuget包引入:Microsoft.Extensions.Logging.Abstractions、Newtonsoft.Json

扩展CusotmLogInterceptor类

using Castle.Core.Logging;
using Castle.DynamicProxy;
using System;
using Microsoft.Extensions.Logging;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Study_ASP.NET_Core_MVC.Interfaces
{
    public class CusotmLogInterceptor : IInterceptor
    {
        /// <summary>
        /// 定义构造函数
        /// </summary>
        private readonly ILogger<CusotmLogInterceptor> _ILogger;
        /// <summary>
        /// 初始化构造函数
        /// </summary>
        /// <param name="logger"></param>
        public CusotmLogInterceptor(ILogger<CusotmLogInterceptor> logger)
        {
            this._ILogger = logger;
        }
        /// <summary>
        /// 切入者逻辑
        /// </summary>
        /// <param name="invocation"></param>
        public void Intercept(IInvocation invocation)
        {
            //方法之前的逻辑
            Console.WriteLine("Begore");
            _ILogger.LogInformation($"参数:{Newtonsoft.Json.JsonConvert.SerializeObject(invocation.Arguments)}");
            _ILogger.LogInformation($"方法{invocation.Method.Name} 开始执行");
            //执行真实的方法
            invocation.Proceed();
            _ILogger.LogInformation($"方法{invocation.Method.Name} 执行完毕");
            //方法之后的逻辑
            Console.WriteLine("After");
            _ILogger.LogInformation($"结果:{Newtonsoft.Json.JsonConvert.SerializeObject(invocation.ReturnValue)}");
        }
    }
}

修改关键类IPhone

using Autofac.Extras.DynamicProxy;
using DocumentFormat.OpenXml.Drawing.Charts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Study_ASP.NET_Core_MVC.Interfaces
{
    /// <summary>
    /// 标识特性支持AOP
    /// </summary>
    [Intercept(typeof(CusotmInterceptor))]
    [Intercept(typeof(CusotmLogInterceptor))]
    public interface IPhone
    {
        IMicroPhone MicroPhone { get; set; }
        IHeadPhone HeadPhone { get; set; }
        /// <summary>
        /// 打电话方法
        /// </summary>
        void Call();
        /// <summary>
        /// 发短信方法
        /// </summary>
        void Text();
        /// <summary>
        /// 玩游戏方法
        /// </summary>
        /// <param name="play"></param>
        /// <returns></returns>
        object PlayGame(object play);
        /// <summary>
        /// 显示当前时间信息
        /// </summary>
        /// <param name="msgInfo">时间信息</param>
        /// <returns></returns>
        string ShowTime(string timeInfo);
    }
    public interface IMicroPhone { }
    public interface IHeadPhone { }
}

修改关键类ApplePhone

using Autofac.Extras.DynamicProxy;
using Study_ASP.NET_Core_MVC.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Study_ASP.Net_Core_MVC.Services
{
    public class ApplePhone : IPhone
    {
        public IMicroPhone MicroPhone { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public IHeadPhone HeadPhone { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public ApplePhone()
        {
            Console.WriteLine("{0}无参构造函数", this.GetType().Name);
        }
        public ApplePhone(IHeadPhone headPhone)
        {
            Console.WriteLine("{0}有参构造函数:{1}", this.GetType().Name,headPhone);
        }

        /// <summary>
        /// 虚方法
        /// 打电话方法
        /// </summary>
        public virtual void Call()
        {
            Console.WriteLine("{0}打电话", this.GetType().Name);
        }
        /// <summary>
        /// 发短信方法
        /// </summary>
        public void Text()
        {
            Console.WriteLine("{0}发短信", this.GetType().Name);
        }
        /// <summary>
        /// 玩游戏方法
        /// </summary>
        /// <param name="play"></param>
        /// <returns></returns>
        public object PlayGame(object play)
        {
            return new
            {
                Id = 123,
                Name = "VinCente"
            };
        }
        /// <summary>
        /// 显示当前时间信息
        /// </summary>
        /// <param name="msgInfo">时间信息</param>
        /// <returns></returns>
        public string ShowTime(string timeInfo)
        {
            Console.WriteLine("显示时间:{0}", timeInfo);
            return $"当前时间:{timeInfo}";
        }
    }
}

修改Program.cs文件

using Autofac;
using Autofac.Extensions.DependencyInjection;
using Autofac.Extras.DynamicProxy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Study_ASP.Net_Core_MVC.Services;
using Study_ASP.NET_Core_MVC.Interfaces;
using Study_ASP.NET_Core_MVC.Models;

//表示整个应用程序,调用CreateBuilder方法创建一个WebApplicationBuilder对象。
var builder = WebApplication.CreateBuilder(args);
//向管道容器添加注册中间件
//添加注册控制器视图中间件
builder.Services.AddControllersWithViews();
//添加注册Session中间件
builder.Services.AddSession();

//添加注册Autofac中间件
//通过工厂替换整合Autofac
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
    //注册服务
    containerBuilder.RegisterType<MicroPhone>().As<IMicroPhone>();
    containerBuilder.RegisterType<HeadPhone>().As<IHeadPhone>();
    //支持AAOP扩展--接口扩展
    containerBuilder.RegisterType<ApplePhone>().As<IPhone>().EnableInterfaceInterceptors();
    //注册切入逻辑
    containerBuilder.RegisterType<CusotmInterceptor>();
    containerBuilder.RegisterType<CusotmLogInterceptor>();
    //注册控制器和抽象关系
    var controllerBaseType = typeof(ControllerBase);
    //支持属性注入到ControllerBase中
    containerBuilder.RegisterAssemblyTypes(typeof(Program).Assembly).Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType).PropertiesAutowired(new CusotmPropertySelector());
});
//添加注册控制器属性注入
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());

//配置管道容器中间件,构造WebApplication实例
var app = builder.Build();
//判断是否是开发模式
if (!app.Environment.IsDevelopment())
{
    //向管道中添加中间件,该中间件将捕获异常、记录异常、重置请求路径并重新执行请求。
    app.UseExceptionHandler("/Shared/Error");
    //向管道中添加用于使用HSTS的中间件,该中间件添加了Strict Transport Security标头。默认值为30天
    app.UseHsts();
}
//向管道添加Session中间件
app.UseSession();
//向管道添加用于将HTTP请求重定向到HTTPS的中间件。
app.UseHttpsRedirection();
//向管道添加为当前请求路径启用静态文件服务
app.UseStaticFiles();
//向管道添加路由配置中间件
app.UseRouting();
//向管道添加鉴权中间件
app.UseAuthentication();
//向管道添加授权中间件
app.UseAuthorization();
//向管道添加默认路由中间件
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
//向管道添加启动应用程序中间件
app.Run();

修改控制器文件

using Autofac;
using Microsoft.AspNetCore.Mvc;
using Study_ASP.Net_Core_MVC.Services;
using Study_ASP.NET_Core_MVC.Interfaces;
using Study_ASP.NET_Core_MVC.Models;
using System.Diagnostics;

namespace Study_ASP.NET_Core_MVC.Controllers
{
    public class HomeController : Controller
    {
        /// <summary>
        /// 定义构造函数
        /// </summary>
        private readonly ILogger<HomeController> _logger;
        private IPhone iPhone;
        /// <summary>
        /// 初始化构造函数
        /// </summary>
        /// <param name="logger">控制器构造函数</param>
        /// <param name="serviceProvider">服务构造函数</param>
        /// <param name="componentContext">上下文构造函数</param>
        /// <param name="iPhone">自定义构造函数</param>
        public HomeController(ILogger<HomeController> logger, IServiceProvider serviceProvider, IComponentContext componentContext, IPhone iPhone)
        {
            //通过调试查看获取的数据
            _logger = logger;
            this.iPhone = iPhone;
        }
        /// <summary>
        /// Get请求
        /// Home控制器
        /// Index方法
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult Index()
        {
            //调用发短信方法
            iPhone.Text();
            //调用打电话方法
            iPhone.Call();
            //调用玩游戏方法
            object oInstance = iPhone.PlayGame(new { playId = 123, playName = "我要玩游戏" });
            //电泳显示实践方法
            ViewBag.ShowTime = iPhone.ShowTime(DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"));
            return View();
        }
    }
}

结果截图

四:Autofac支持AOP扩展缓存功能

扩展CusotmCacheInterceptor类:

using Castle.DynamicProxy;
using Microsoft.Extensions.Logging;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Study_ASP.NET_Core_MVC.Interfaces
{
    public class CusotmCacheInterceptor : IInterceptor
    {
        /// <summary>
        /// 定义构造函数
        /// </summary>
        private readonly ILogger<CusotmCacheInterceptor> _ILogger;
        /// <summary>
        /// 初始化构造函数
        /// </summary>
        /// <param name="logger"></param>
        public CusotmCacheInterceptor(ILogger<CusotmCacheInterceptor> logger)
        {
            this._ILogger = logger;
        }
        //定义字典
        private static Dictionary<string, object> _cacheDictionary = new Dictionary<string, object>();
        /// <summary>
        /// 切入者逻辑
        /// </summary>
        /// <param name="invocation"></param>
        public void Intercept(IInvocation invocation)
        {
            //方法之前检查缓存的结果
            //定义Key
            string cacheKey = invocation.Method.Name;
            //判断当前是否有缓存结果
            if (_cacheDictionary.ContainsKey(cacheKey))
            {
                invocation.ReturnValue = _cacheDictionary[cacheKey];
            }
            else
            {
                //执行真实的方法
                invocation.Proceed();
                //方法之后保存缓存的结果
                _cacheDictionary[cacheKey] = invocation.ReturnValue;
            }
        }
    }
}

修改关键类IPhone

using Autofac.Extras.DynamicProxy;
using DocumentFormat.OpenXml.Drawing.Charts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Study_ASP.NET_Core_MVC.Interfaces
{
    /// <summary>
    /// 标识特性支持AOP
    /// </summary>
    [Intercept(typeof(CusotmCacheInterceptor))]
    public interface IPhone
    {
        IMicroPhone MicroPhone { get; set; }
        IHeadPhone HeadPhone { get; set; }
        /// <summary>
        /// 打电话方法
        /// </summary>
        void Call();
        /// <summary>
        /// 发短信方法
        /// </summary>
        void Text();
        /// <summary>
        /// 玩游戏方法
        /// </summary>
        /// <param name="play"></param>
        /// <returns></returns>
        object PlayGame(object play);
        /// <summary>
        /// 显示当前时间信息
        /// </summary>
        /// <param name="msgInfo">时间信息</param>
        /// <returns></returns>
        string ShowTime(string timeInfo);
    }
    public interface IMicroPhone { }
    public interface IHeadPhone { }
}

修改关键类ApplePhone

using Autofac.Extras.DynamicProxy;
using Study_ASP.NET_Core_MVC.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Study_ASP.Net_Core_MVC.Services
{
    public class ApplePhone : IPhone
    {
        public IMicroPhone MicroPhone { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public IHeadPhone HeadPhone { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public ApplePhone()
        {
            Console.WriteLine("{0}无参构造函数", this.GetType().Name);
        }
        public ApplePhone(IHeadPhone headPhone)
        {
            Console.WriteLine("{0}有参构造函数:{1}", this.GetType().Name,headPhone);
        }

        /// <summary>
        /// 虚方法
        /// 打电话方法
        /// </summary>
        public virtual void Call()
        {
            Console.WriteLine("{0}打电话", this.GetType().Name);
        }
        /// <summary>
        /// 发短信方法
        /// </summary>
        public void Text()
        {
            Console.WriteLine("{0}发短信", this.GetType().Name);
        }
        /// <summary>
        /// 玩游戏方法
        /// </summary>
        /// <param name="play"></param>
        /// <returns></returns>
        public object PlayGame(object play)
        {
            return new
            {
                Id = 123,
                Name = "VinCente",
                DateTime = DateTime.Now
            };
        }
        /// <summary>
        /// 显示当前时间信息
        /// </summary>
        /// <param name="msgInfo">时间信息</param>
        /// <returns></returns>
        public string ShowTime(string timeInfo)
        {
            Console.WriteLine("显示时间:{0}", timeInfo);
            return $"当前时间:{timeInfo}";
        }
    }
}

修改Program.cs文件

using Autofac;
using Autofac.Extensions.DependencyInjection;
using Autofac.Extras.DynamicProxy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Study_ASP.Net_Core_MVC.Services;
using Study_ASP.NET_Core_MVC.Interfaces;
using Study_ASP.NET_Core_MVC.Models;

//表示整个应用程序,调用CreateBuilder方法创建一个WebApplicationBuilder对象。
var builder = WebApplication.CreateBuilder(args);
//向管道容器添加注册中间件
//添加注册控制器视图中间件
builder.Services.AddControllersWithViews();
//添加注册Session中间件
builder.Services.AddSession();

//添加注册Autofac中间件
//通过工厂替换整合Autofac
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
    //注册服务
    containerBuilder.RegisterType<MicroPhone>().As<IMicroPhone>();
    containerBuilder.RegisterType<HeadPhone>().As<IHeadPhone>();
    //支持AAOP扩展--接口扩展
    containerBuilder.RegisterType<ApplePhone>().As<IPhone>().EnableInterfaceInterceptors();
    //注册切入逻辑
    containerBuilder.RegisterType<Study_ASP.NET_Core_MVC.Interfaces.CusotmInterceptor>();
    containerBuilder.RegisterType<Study_ASP.NET_Core_MVC.Interfaces.CusotmLogInterceptor>();
    containerBuilder.RegisterType<Study_ASP.NET_Core_MVC.Interfaces.CusotmCacheInterceptor>();
    //注册控制器和抽象关系
    var controllerBaseType = typeof(ControllerBase);
    //支持属性注入到ControllerBase中
    containerBuilder.RegisterAssemblyTypes(typeof(Program).Assembly).Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType).PropertiesAutowired(new CusotmPropertySelector());
});
//添加注册控制器属性注入
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());

//配置管道容器中间件,构造WebApplication实例
var app = builder.Build();
//判断是否是开发模式
if (!app.Environment.IsDevelopment())
{
    //向管道中添加中间件,该中间件将捕获异常、记录异常、重置请求路径并重新执行请求。
    app.UseExceptionHandler("/Shared/Error");
    //向管道中添加用于使用HSTS的中间件,该中间件添加了Strict Transport Security标头。默认值为30天
    app.UseHsts();
}
//向管道添加Session中间件
app.UseSession();
//向管道添加用于将HTTP请求重定向到HTTPS的中间件。
app.UseHttpsRedirection();
//向管道添加为当前请求路径启用静态文件服务
app.UseStaticFiles();
//向管道添加路由配置中间件
app.UseRouting();
//向管道添加鉴权中间件
app.UseAuthentication();
//向管道添加授权中间件
app.UseAuthorization();
//向管道添加默认路由中间件
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
//向管道添加启动应用程序中间件
app.Run();

修改控制器文件

using Autofac;
using Microsoft.AspNetCore.Mvc;
using Study_ASP.Net_Core_MVC.Services;
using Study_ASP.NET_Core_MVC.Interfaces;
using Study_ASP.NET_Core_MVC.Models;
using System.Diagnostics;

namespace Study_ASP.NET_Core_MVC.Controllers
{
    public class HomeController : Controller
    {
        /// <summary>
        /// 定义构造函数
        /// </summary>
        private readonly ILogger<HomeController> _logger;
        private IPhone iPhone;
        /// <summary>
        /// 初始化构造函数
        /// </summary>
        /// <param name="logger">控制器构造函数</param>
        /// <param name="serviceProvider">服务构造函数</param>
        /// <param name="componentContext">上下文构造函数</param>
        /// <param name="iPhone">自定义构造函数</param>
        public HomeController(ILogger<HomeController> logger, IServiceProvider serviceProvider, IComponentContext componentContext, IPhone iPhone)
        {
            //通过调试查看获取的数据
            _logger = logger;
            this.iPhone = iPhone;
        }
        /// <summary>
        /// Get请求
        /// Home控制器
        /// Index方法
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public IActionResult Index()
        {
            //调用发短信方法
            iPhone.Text();
            //调用打电话方法
            iPhone.Call();
            //调用玩游戏方法
            object oInstance = iPhone.PlayGame(new { playId = 123, playName = "我要玩游戏" });
            //显示时间方法
            ViewBag.ShowTime = iPhone.ShowTime(DateTime.Now.ToString("yyyy-MM-dd HH-mm-ss"));
            return View();
        }
    }
}

结果截图

 

五:Autofac支持AOP扩展IInterceptorSelector

以上扩展方法需要在方法上标注特性。扩展使用IInterceptorSelector时,只需要在Program中注册服务扩展接口时注册,无需在方法上标注特性。

扩展CusotmInterceptorSelector类

using Castle.DynamicProxy;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;

namespace Study_ASP.NET_Core_MVC.Interfaces
{
    public class CusotmInterceptorSelector : IInterceptorSelector
    {
        /// <summary>
        /// 让我们选择使用那个IInterceptor
        /// </summary>
        /// <param name="type"></param>
        /// <param name="method"></param>
        /// <param name="interceptors"></param>
        /// <returns></returns>
        /// <exception cref="NotImplementedException"></exception>
        public IInterceptor[] SelectInterceptors(Type type, MethodInfo method, IInterceptor[] interceptors)
        {
            return new IInterceptor[]
            {
                new CusotmInterceptor(),
                new CusotmCacheInterceptor()
            };
        }
    }
}

修改关键类Program.cs文件

using Autofac;
using Autofac.Extensions.DependencyInjection;
using Autofac.Extras.DynamicProxy;
using Castle.DynamicProxy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.Extensions.DependencyInjection.Extensions;
using Study_ASP.Net_Core_MVC.Services;
using Study_ASP.NET_Core_MVC.Interfaces;
using Study_ASP.NET_Core_MVC.Models;

//表示整个应用程序,调用CreateBuilder方法创建一个WebApplicationBuilder对象。
var builder = WebApplication.CreateBuilder(args);
//向管道容器添加注册中间件
//添加注册控制器视图中间件
builder.Services.AddControllersWithViews();
//添加注册Session中间件
builder.Services.AddSession();

//添加注册Autofac中间件
//通过工厂替换整合Autofac
builder.Host.UseServiceProviderFactory(new AutofacServiceProviderFactory());
builder.Host.ConfigureContainer<ContainerBuilder>(containerBuilder =>
{
    //注册服务
    containerBuilder.RegisterType<MicroPhone>().As<IMicroPhone>();
    containerBuilder.RegisterType<HeadPhone>().As<IHeadPhone>();
    //支持AAOP扩展--接口扩展
    containerBuilder.RegisterType<ApplePhone>().As<IPhone>().EnableInterfaceInterceptors(new ProxyGenerationOptions()
    {
        Selector= new CusotmInterceptorSelector()
    });
    //注册切入逻辑
    containerBuilder.RegisterType<Study_ASP.NET_Core_MVC.Interfaces.CusotmInterceptor>();
    containerBuilder.RegisterType<Study_ASP.NET_Core_MVC.Interfaces.CusotmLogInterceptor>();
    containerBuilder.RegisterType<Study_ASP.NET_Core_MVC.Interfaces.CusotmCacheInterceptor>();
    //注册控制器和抽象关系
    var controllerBaseType = typeof(ControllerBase);
    //支持属性注入到ControllerBase中
    containerBuilder.RegisterAssemblyTypes(typeof(Program).Assembly).Where(t => controllerBaseType.IsAssignableFrom(t) && t != controllerBaseType).PropertiesAutowired(new CusotmPropertySelector());
});
//添加注册控制器属性注入
builder.Services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>());

//配置管道容器中间件,构造WebApplication实例
var app = builder.Build();
//判断是否是开发模式
if (!app.Environment.IsDevelopment())
{
    //向管道中添加中间件,该中间件将捕获异常、记录异常、重置请求路径并重新执行请求。
    app.UseExceptionHandler("/Shared/Error");
    //向管道中添加用于使用HSTS的中间件,该中间件添加了Strict Transport Security标头。默认值为30天
    app.UseHsts();
}
//向管道添加Session中间件
app.UseSession();
//向管道添加用于将HTTP请求重定向到HTTPS的中间件。
app.UseHttpsRedirection();
//向管道添加为当前请求路径启用静态文件服务
app.UseStaticFiles();
//向管道添加路由配置中间件
app.UseRouting();
//向管道添加鉴权中间件
app.UseAuthentication();
//向管道添加授权中间件
app.UseAuthorization();
//向管道添加默认路由中间件
app.MapControllerRoute(
    name: "default",
    pattern: "{controller=Home}/{action=Index}/{id?}");
//向管道添加启动应用程序中间件
app.Run();

修改关键类IPhone

using Autofac.Extras.DynamicProxy;
using DocumentFormat.OpenXml.Drawing.Charts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Study_ASP.NET_Core_MVC.Interfaces
{
    public interface IPhone
    {
        IMicroPhone MicroPhone { get; set; }
        IHeadPhone HeadPhone { get; set; }
        /// <summary>
        /// 打电话方法
        /// </summary>
        void Call();
        /// <summary>
        /// 发短信方法
        /// </summary>
        void Text();
        /// <summary>
        /// 玩游戏方法
        /// </summary>
        /// <param name="play"></param>
        /// <returns></returns>
        object PlayGame(object play);
        /// <summary>
        /// 显示当前时间信息
        /// </summary>
        /// <param name="msgInfo">时间信息</param>
        /// <returns></returns>
        string ShowTime(string timeInfo);
    }
    public interface IMicroPhone { }
    public interface IHeadPhone { }
}

修改关键类ApplePhone

using Autofac.Extras.DynamicProxy;
using Study_ASP.NET_Core_MVC.Interfaces;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Study_ASP.Net_Core_MVC.Services
{
    public class ApplePhone : IPhone
    {
        public IMicroPhone MicroPhone { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public IHeadPhone HeadPhone { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }
        public ApplePhone()
        {
            Console.WriteLine("{0}无参构造函数", this.GetType().Name);
        }
        public ApplePhone(IHeadPhone headPhone)
        {
            Console.WriteLine("{0}有参构造函数:{1}", this.GetType().Name,headPhone);
        }

        /// <summary>
        /// 虚方法
        /// 打电话方法
        /// </summary>
        public virtual void Call()
        {
            Console.WriteLine("{0}打电话", this.GetType().Name);
        }
        /// <summary>
        /// 发短信方法
        /// </summary>
        public void Text()
        {
            Console.WriteLine("{0}发短信", this.GetType().Name);
        }
        /// <summary>
        /// 玩游戏方法
        /// </summary>
        /// <param name="play"></param>
        /// <returns></returns>
        public object PlayGame(object play)
        {
            return new
            {
                Id = 123,
                Name = "VinCente",
                DateTime = DateTime.Now
            };
        }
        /// <summary>
        /// 显示当前时间信息
        /// </summary>
        /// <param name="msgInfo">时间信息</param>
        /// <returns></returns>
        public string ShowTime(string timeInfo)
        {
            Console.WriteLine("显示时间:{0}", timeInfo);
            return $"当前时间:{timeInfo}";
        }
    }
}

结果截图

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Vin Cente

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值