
用Autofac增强容器能力:引入面向切面编程(AOP)的能力
基本介绍
Autofac是.NET里IOC(Inversion of Control)容器的一种,同类的框架还有Spring.NET,Unity,Castle等。可以通过NuGet方式将其添加到项目中使用。
Autofac官方网站:http://autofac.org/
创建项目
项目目录
安装 Autofac 依赖包
安装 Autofac.Extras.DynamicProxy
Install-Package Autofac.Extras.DynamicProxy -Version 5.0.0
dotnet add package Autofac.Extras.DynamicProxy --version 5.0.0
安装 Autofac.Extensions.DependencyInjection
Install-Package Autofac.Extensions.DependencyInjection -Version 6.0.0
dotnet add package Autofac.Extensions.DependencyInjection --version 6.0.0
项目内容
WeatherForecastController.cs
[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;
}
}
MyDI.cs
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; }
}
Interceptor.cs
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}");
}
}
MyService.cs
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
{
}
Startup.cs
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();
});
}
Program.cs
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>();
});
}
基于名称的注入
修改Startup.cs
ConfigureContainer 方法
builder.RegisterType<MyService>().As<IMyService>();
#region 命名注册
builder.RegisterType<MyServiceV2>().Named<IMyService>("service2");
#endregion
Configure 方法
var servicenamed = this.AutofacContainer.Resolve<IMyService>();
servicenamed.ShowCode();
var service = this.AutofacContainer.ResolveNamed<IMyService>("service2");
service.ShowCode();
运行结果
属性注入
属性注入前
属性注入后
基于动态代理的AOP
子容器
其他
请大家自行感受,期待评论区分享简洁的认识当中的区别!助我成长!谢谢!
欢迎加群讨论技术,1群:677373950(满了,可以加,但通过不了),2群:656732739
评价
排名
2
文章
657
粉丝
44
评论
93
docker中Sware集群与service
尘叶心繁 : 想学呀!我教你呀
一个bug让程序员走上法庭 索赔金额达400亿日元
叼着奶瓶逛酒吧 : 所以说做程序员也要懂点法律知识
.net core 塑形资源
剑轩 : 收藏收藏
映射AutoMapper
剑轩 :
好是好,这个对效率影响大不大哇,效率高不高
一个bug让程序员走上法庭 索赔金额达400亿日元
剑轩 : 有点可怕
ASP.NET Core 服务注册生命周期
剑轩 :
http://www.tnblog.net/aojiancc2/article/details/167
ICP备案 :渝ICP备18016597号-1
网站信息:2018-2025TNBLOG.NET
技术交流:群号656732739
联系我们:contact@tnblog.net
公网安备:
50010702506256


欢迎加群交流技术