-
Notifications
You must be signed in to change notification settings - Fork 1
Open
Description
第三方 DI
容器 Autofac
与 AOP
Autofac
是什么
这个是一种老牌的 Ioc
容器,很多大型项目都在使用,轻量级,而且性能很高。
为什么使用 Autofac
而不是系统内置容器
系统内置容器一般只支持构造方法注入,不支持名称注入,属性注入,AOP
等。
Autofac
使用
Autofac
为什么可以替换.NetCore
内置容器
UseServiceProviderFactory<TContainerBuilder>
需要传递一个( IServiceProviderFactory<TContainerBuilder
>
接口实现类
IHostBuilder UseServiceProviderFactory<TContainerBuilder>(IServiceProviderFactory<TContainerBuilder> factory);
Autofac
实现了 public class AutofacServiceProviderFactory : IServiceProviderFactory<ContainerBuilder>
,
即接口多态的使用。
Nuget
引入Autofac
包
Autofac.Extensions.DependencyInjection
Autofact.DynamicProxy
Program.cs
中注册第三方容器
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)
//注册第三方容器
.UseServiceProviderFactory(new AutofacServiceProviderFactory())
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();
})
Startup
中添加新的服务注册方法
只要方法正确添加,即可完整的无缝和前面的内置框架集成。
Startup
类中服务注册:
using Autofac.Extras.DynamicProxy;
// 系统内置的方法,无需改变
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
//注入我们自己需要的服务
//services.AddTransient<IServiceA, ObjectA>();
//services.AddSingleton<IServiceB, ObjectB>();
//services.AddScoped<IServiceC, ObjectC>();
services.AddTransient<IServiceD, ObjectD>();
}
// Autofac 注册服务
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterType<ObjectA>().As<IServiceA>().InstancePerDependency();
builder.RegisterType<ObjectB>().As<IServiceB>().SingleInstance();
builder.RegisterType<ObjectC>().As<IServiceC>().InstancePerLifetimeScope();
}
服务 Provider: 跟之前一样,无需改变,实现无缝集成。
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly ILoggerFactory _loggerFactory;
private readonly IServiceA _serviceA;
private readonly IServiceB _serviceB;
private readonly IServiceC _serviceC;
public HomeController(ILogger<HomeController> logger,ILoggerFactory loggerFactory,
IServiceA serviceA, IServiceB serviceB, IServiceC serviceC)
{
_logger = logger;
_loggerFactory = loggerFactory;
this._serviceA = serviceA;
this._serviceB = serviceB;
this._serviceC = serviceC;
}
public IActionResult Index()
{
this._serviceA.Operation();
this._serviceB.Operation();
this._serviceC.Operation();
this._loggerFactory.CreateLogger<HomeController>().LogInformation("这个是 this._loggerFactory.LogInformation的输出!");
this._loggerFactory.CreateLogger<HomeController>().LogWarning("这个是 this._loggerFactory.LogWarning!");
this._loggerFactory.CreateLogger<HomeController>().LogError("这个是 this._loggerFactory.LogError!");
return View();
}
}
Autofac
中使用 AOP
模型
--------------------
--------------------
课堂订单提交业务
--------------------
--------------------
- 定义接口,实现接口
/// <summary>
/// 核心业务接口
/// </summary>
public interface IMyStudy
{
void StudyNetCore(string content);
}
public class MyStudy : IMyStudy
{
public void StudyNetCore(string content)
{
//实际开发中,应该在这个地方写具体的实现
Console.WriteLine($"我们现在开始学习:{content}");
}
//扩展1...
//扩展2...
}
- 扩展业务,实现拦截器接口,并在原有业务类中,增加拦截器接口特性
using Castle.DynamicProxy;
public class MyStudyAOP : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine("预习...");
invocation.Proceed();//调用核心的业务
Console.WriteLine("巩固...");
}
}
/// <summary>
/// 核心业务接口添加拦截器
/// </summary>
public interface IMyStudy
{
void StudyNetCore(string content);
}
[Intercept(typeof(MyStudyAOP))] //通过特性拦截器扩展的业务
public class MyStudy : IMyStudy
{
public void StudyNetCore(string content)
{
//实际开发中,应该在这个地方写具体的实现
Console.WriteLine($"我们现在开始学习:{content}");
}
}
- 服务注册
在 Startup
类中注册服务
using Autofac.Extras.DynamicProxy;
public void ConfigureContainer(ContainerBuilder builder)
{
builder.RegisterType<ObjectA>().As<IServiceA>().InstancePerDependency();
builder.RegisterType<ObjectB>().As<IServiceB>().SingleInstance();
builder.RegisterType<ObjectC>().As<IServiceC>().InstancePerLifetimeScope();
//注册扩展业务类
builder.Register(c => new MyStudyAOP());
//注册核心业务类,并开启接口拦截器
builder.RegisterType<MyStudy>().As<IMyStudy>().EnableInterfaceInterceptors();
}
问题:随着业务越来越复杂,注册的服务越来越多,代码越来越复杂
解决:独立自定义一个容器注册类,重写 Load
方法,完成服务注册,和扩展业务注册
using Autofac;
using Autofac.Extras.DynamicProxy
public class CustomAutofacModule:Autofac.Module
{
//重写Load方法
protected override void Load(ContainerBuilder containerBuilder)
{
var assembly = this.GetType().GetTypeInfo().Assembly;
var builder = new ContainerBuilder();
var manager = new ApplicationPartManager();
manager.ApplicationParts.Add(new AssemblyPart(assembly));
manager.FeatureProviders.Add(new ControllerFeatureProvider());
var feature = new ControllerFeature();
manager.PopulateFeature(feature);
//注册我们自己需要的各种服务
containerBuilder.RegisterType<ObjectA>().As<IServiceA>().InstancePerDependency();
containerBuilder.RegisterType<ObjectB>().As<IServiceB>().SingleInstance();
containerBuilder.RegisterType<ObjectC>().As<IServiceC>().InstancePerLifetimeScope();
//注册扩展业务类
containerBuilder.Register(c => new MyStudyAOP());
//注册核心业务类,并开启接口拦截器
containerBuilder.RegisterType<MyStudy>().As<IMyStudy>().EnableInterfaceInterceptors();
}
}
修改注册服务:
using Autofac.Extras.DynamicProxy;
public void ConfigureContainer(ContainerBuilder builder)
{
//使用模块化集中注册服务的方式
builder.RegisterModule<CustomAutofacModule>();
}
服务调用:
public class HomeController : Controller
{
private readonly ILogger<HomeController> _logger;
private readonly ILoggerFactory _loggerFactory;
private readonly IServiceA _serviceA;
private readonly IServiceB _serviceB;
private readonly IServiceC _serviceC;
private readonly IMyStudy _imyStudy;
public HomeController(ILogger<HomeController> logger,ILoggerFactory loggerFactory,
IServiceA serviceA, IServiceB serviceB, IServiceC serviceC,IMyStudy imyStudy)
{
_logger = logger;
_loggerFactory = loggerFactory;
this._serviceA = serviceA;
this._serviceB = serviceB;
this._serviceC = serviceC;
this._imyStudy = imyStudy;
}
public IActionResult Index()
{
this._imyStudy.StudyNetCore("依赖注入容器DI和AOP!");
return View();
}
}
Metadata
Metadata
Assignees
Labels
No labels