用Autofac增强容器能力:引入面向切面编程(AOP)的能力 电脑版发表于:2020/5/31 14:49 ![.netcore](https://img.tnblog.net/arcimg/hb/c857299a86d84ee7b26d181a31e58234.jpg ".netcore") >#用Autofac增强容器能力:引入面向切面编程(AOP)的能力 [TOC] <br/> 基本介绍 ------------ <br/> >Autofac是.NET里IOC(Inversion of Control)容器的一种,同类的框架还有Spring.NET,Unity,Castle等。可以通过NuGet方式将其添加到项目中使用。 >Autofac官方网站:http://autofac.org/ <br/> 创建项目 ------------ <br/> >###项目目录 ![](https://img.tnblog.net/arcimg/hb/9ec4bb2f3dd8443998979fa1ff2703c5.png) >###安装 Autofac 依赖包 ![autofac](https://img.tnblog.net/arcimg/hb/43e56666ff0249f586b98e040206402a.png "autofac") 安装 **Autofac.Extras.DynamicProxy** ```bash Install-Package Autofac.Extras.DynamicProxy -Version 5.0.0 dotnet add package Autofac.Extras.DynamicProxy --version 5.0.0 ``` 安装 **Autofac.Extensions.DependencyInjection ** ```bash Install-Package Autofac.Extensions.DependencyInjection -Version 6.0.0 dotnet add package Autofac.Extensions.DependencyInjection --version 6.0.0 ``` >###项目内容 <br/> ><font style="color:#2ecc71;font-weight:bold;">WeatherForecastController.cs</font> ```csharp [ApiController] [Route("[controller]")] public class WeatherForecastController : ControllerBase { private readonly ILogger<WeatherForecastController> _logger; public WeatherForecastController(ILogger<WeatherForecastController> logger) { _logger = logger; } [HttpGet] public int Get([FromServices]IEnumerable<IMyService> list) { foreach (var item in list) { item.ShowCode(); } return 0; } } ``` ><font style="color:#2ecc71;font-weight:bold;">MyDI.cs</font> ```csharp public class MyDIServiceProviderFactory : IServiceProviderFactory<MyContainerBuilder> { public MyContainerBuilder CreateBuilder(IServiceCollection services) { return new MyContainerBuilder() { Services = services }; } public IServiceProvider CreateServiceProvider(MyContainerBuilder containerBuilder) { return new MyServiceProvider(containerBuilder.Services.BuildServiceProvider()); } } public class MyServiceProvider : IServiceProvider { IServiceProvider _serviceProvider; public MyServiceProvider(IServiceProvider serviceProvider) { _serviceProvider = serviceProvider; } public object GetService(Type serviceType) { Console.WriteLine($"正在创建对象:{serviceType.FullName}"); return _serviceProvider.GetService(serviceType); } } public class MyContainerBuilder { internal IServiceCollection Services { get; set; } } ``` ><font style="color:#2ecc71;font-weight:bold;">Interceptor.cs</font> ```csharp public class MyInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { Console.WriteLine($"Intercept before,Method:{invocation.Method.Name}"); invocation.Proceed(); Console.WriteLine($"Intercept after,Method:{invocation.Method.Name}"); } } ``` ><font style="color:#2ecc71;font-weight:bold;">MyService.cs</font> ```csharp public interface IMyService { void ShowCode(); } public class MyService : IMyService { public void ShowCode() { Console.WriteLine($"MyService.ShowCode:{GetHashCode()}"); } } public class MyServiceV2 : IMyService { public MyNameService NameService { get; set; } public void ShowCode() { Console.WriteLine($"MyServiceV2.ShowCode:{GetHashCode()},NameService是否为空:{NameService == null}"); } } public class MyNameService { } ``` ><font style="color:#2ecc71;font-weight:bold;">Startup.cs</font> ```csharp public Startup(IConfiguration configuration) { Configuration = configuration; } public IConfiguration Configuration { get; } public void ConfigureServices(IServiceCollection services) { services.AddControllers().AddControllersAsServices(); } public void ConfigureContainer(ContainerBuilder builder) { //builder.RegisterType<MyService>().As<IMyService>(); #region 命名注册 //builder.RegisterType<MyServiceV2>().Named<IMyService>("service2"); #endregion #region 属性注册 //builder.RegisterType<MyNameService>(); //builder.RegisterType<MyServiceV2>().As<IMyService>().PropertiesAutowired(); #endregion #region AOP // builder.RegisterType<MyInterceptor>(); // builder.RegisterType<MyNameService>(); // builder.RegisterType<MyServiceV2>().As<IMyService>().PropertiesAutowired().InterceptedBy(typeof(MyInterceptor)).EnableInterfaceInterceptors(); #endregion #region 子容器 //builder.RegisterType<MyNameService>().InstancePerMatchingLifetimeScope("myscope"); #endregion } public ILifetimeScope AutofacContainer { get; private set; } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { this.AutofacContainer = app.ApplicationServices.GetAutofacRoot(); #region 1,2,3 // var servicenamed = this.AutofacContainer.Resolve<IMyService>(); // servicenamed.ShowCode(); //var service = this.AutofacContainer.ResolveNamed<IMyService>("service2"); //service.ShowCode(); #endregion #region 子容器 using (var myscope = AutofacContainer.BeginLifetimeScope("myscope")) { var service0 = myscope.Resolve<MyNameService>(); using (var scope = myscope.BeginLifetimeScope()) { var service1 = scope.Resolve<MyNameService>(); var service2 = scope.Resolve<MyNameService>(); Console.WriteLine($"service1=service2:{service1 == service2}"); Console.WriteLine($"service1=service0:{service1 == service0}"); } } #endregion if (env.IsDevelopment()) { app.UseDeveloperExceptionPage(); } app.UseHttpsRedirection(); app.UseRouting(); app.UseAuthorization(); app.UseEndpoints(endpoints => { endpoints.MapControllers(); }); } ``` ><font style="color:#2ecc71;font-weight:bold;">Program.cs</font> ```csharp public class Program { public static void Main(string[] args) { CreateHostBuilder(args).Build().Run(); } public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args) .UseServiceProviderFactory(new AutofacServiceProviderFactory()) .ConfigureWebHostDefaults(webBuilder => { webBuilder.UseStartup<Startup>(); }); } ``` <br/> 基于名称的注入 ------------ <br/> >修改<font style="color:#2ecc71;font-weight:bold;">Startup.cs</font> <br/> >ConfigureContainer 方法 ```bash builder.RegisterType<MyService>().As<IMyService>(); #region 命名注册 builder.RegisterType<MyServiceV2>().Named<IMyService>("service2"); #endregion ``` >Configure 方法 ```bash var servicenamed = this.AutofacContainer.Resolve<IMyService>(); servicenamed.ShowCode(); var service = this.AutofacContainer.ResolveNamed<IMyService>("service2"); service.ShowCode(); ``` >运行结果 ![](https://img.tnblog.net/arcimg/hb/9e15e27c33254622a24ad831d269582d.png) <br/> 属性注入 ------------ <br/> >属性注入前 ![](https://img.tnblog.net/arcimg/hb/06980a4ca17b400ba714b8b71cff1926.png) >属性注入后 ![](https://img.tnblog.net/arcimg/hb/3ac0cf06210348ca88df73d29b3a82ea.png) <br/> 基于动态代理的AOP ------------ <br/> ![](https://img.tnblog.net/arcimg/hb/b3cd88ddfd7742918dd29c5727ebb036.png) <br/> 子容器 ------------ <br/> ![](https://img.tnblog.net/arcimg/hb/208f15badf9f43c9b2986875c45c04ec.png) <br/> 其他 ------------ <br/> > 请大家自行感受,期待评论区分享简洁的认识当中的区别!助我成长!谢谢!