原有core 3.1内置了ioc容器和DI注入,有个缺点就算不能够实现AOP,所以使用第三方autofact来代替原有的容器
一:原有core 3.1的容器使用方法
配置服务
public void ConfigureServices(IServiceCollection services)
{
services.AddSession();
services.AddControllersWithViews();
//只能构造函数注入--需要一个构造函数超集
services.AddTransient<ITestServiceA, TestServiceA>();//瞬时
services.AddSingleton<ITestServiceB, TestServiceB>();//单例
services.AddScoped<ITestServiceC, TestServiceC>();//作用域单例--一次请求一个实例
//作用域其实依赖于ServiceProvider(这个自身是根据请求的),跟多线程没关系
services.AddTransient<ITestServiceD, TestServiceD>();
services.AddTransient<ITestServiceE, TestServiceE>();
}
构造函数注入
public class SecondController : Controller
{
private readonly ILogger<SecondController> _logger;
private readonly ILoggerFactory _loggerFactory;
private readonly ITestServiceA _iTestServiceA;
private readonly ITestServiceB _iTestServiceB;
private readonly ITestServiceC _iTestServiceC;
private readonly ITestServiceD _iTestServiceD;
private readonly ITestServiceE _iTestServiceE;
private readonly IServiceProvider _iServiceProvider;
///
/// 来自DI依赖注入---构造函数注入---构造A对象依赖B对象,自动初始化B对象传入
///
/// 有个容器,负责构造SecondController(反射)--反射构造函数--需要B--再构造B---然后再构造A
///
///
///
public SecondController(ILogger<SecondController> logger,
ILoggerFactory loggerFactory
, ITestServiceA testServiceA
, ITestServiceB testServiceB
, ITestServiceC testServiceC
, ITestServiceD testServiceD
, ITestServiceE testServiceE
, IServiceProvider serviceProvider)
//一次注入这么多,可能用不上,能不能我自己生成? 不建议,
//1 大部分对象生成其实很快,且不占资源--特殊可以自己控制
//2 对象生命周期不同,注入的是跟controller的,action是跟方法的
{
this._logger = logger;
this._loggerFactory = loggerFactory;
this._iTestServiceA = testServiceA;
this._iTestServiceB = testServiceB;
this._iTestServiceC = testServiceC;
this._iTestServiceD = testServiceD;
this._iTestServiceE = testServiceE;
this._iServiceProvider = serviceProvider;
}
///
/// 纯属测试 毫无意义
///
private static ITestServiceC _iTestServiceCStatic = null;
private static ITestServiceB _iTestServiceBStatic = null;
public IActionResult Index()
{
//ITestServiceA testServiceA = new TestServiceA();
this._logger.LogWarning("This is SecondController Index");
var c = this._iServiceProvider.GetService<ITestServiceC>();
Console.WriteLine($"cc {object.ReferenceEquals(this._iTestServiceC, c)}");//T/F
if (_iTestServiceCStatic == null)
{
_iTestServiceCStatic = _iTestServiceC;
}
else
{
Console.WriteLine($"C&C {object.ReferenceEquals(this._iTestServiceC, _iTestServiceCStatic)}");//两次不同的请求 //T/F
}
if (_iTestServiceBStatic == null)
{
_iTestServiceBStatic = _iTestServiceB;
}
else
{
Console.WriteLine($"B&B:{object.ReferenceEquals(this._iTestServiceB, _iTestServiceBStatic)}");//两次不同的请求 //T/F
}
this._iTestServiceA.Show();
this._iTestServiceB.Show();
this._iTestServiceC.Show();
this._iTestServiceD.Show();
this._iTestServiceE.Show();
return View();
}
}
二:autofac的容器使用方法
首先nuget引入:Autofac.Extensions.Depend
Profram中加入如下代码
public static IHostBuilder CreateHostBuilder(string[] args) =>
Host.CreateDefaultBuilder(args)//就是指定kestrel
//.ConfigureLogging(loggingBuilder =>
// {
// loggingBuilder.AddLog4Net();//需要配置文件
// })
.UseServiceProviderFactory(new AutofacServiceProviderFactory())//设置工厂来替换实例
.ConfigureWebHostDefaults(webBuilder =>
{
webBuilder.UseStartup<Startup>();//靠Startup来串起来MVC
});
Startup中加入如下代码
public void ConfigureContainer(ContainerBuilder containerBuilder)
{
//containerBuilder.RegisterType().As().SingleInstance();
containerBuilder.RegisterModule<CustomAutofacModule>();
}
对应于CustomAutofacModule类
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);
builder.RegisterType<ApplicationPartManager>().AsSelf().SingleInstance();
builder.RegisterTypes(feature.Controllers.Select(ti => ti.AsType()).ToArray()).PropertiesAutowired();
//containerBuilder.RegisterType().PropertiesAutowired();
//containerBuilder.Register(c => new CustomAutofacAop());//允许使用AOP,注册
containerBuilder.RegisterType<TestServiceA>().As<ITestServiceA>().SingleInstance().PropertiesAutowired();
containerBuilder.RegisterType<TestServiceC>().As<ITestServiceC>();
containerBuilder.RegisterType<TestServiceB>().As<ITestServiceB>();
containerBuilder.RegisterType<TestServiceD>().As<ITestServiceD>();
containerBuilder.RegisterType<TestServiceE>().As<ITestServiceE>();
// 允许当前注册的这个服务实例使用Aop
//containerBuilder.RegisterType().As();//.EnableInterfaceInterceptors();
//containerBuilder.Register();
//containerBuilder.RegisterType().As();
//containerBuilder.RegisterType().As();
//containerBuilder.RegisterType().As();
}
}
autofactAOP的实现首先引入:Autofac.Extras.DynamicProxy
public class CustomAutofacAop : IInterceptor
{
public void Intercept(IInvocation invocation)
{
Console.WriteLine($"invocation.Methond={invocation.Method}");
Console.WriteLine($"invocation.Arguments={string.Join(",", invocation.Arguments)}");
invocation.Proceed(); //继续执行
Console.WriteLine($"方法{invocation.Method}执行完成了");
}
}
public interface IA
{
void Show(int id, string name);
}
[Intercept(typeof(CustomAutofacAop))]
public class A : IA
{
public void Show(int id, string name)
{
Console.WriteLine($"This is {id} _ {name}");
}
}
配置文件实现
public class CustomAutofacModule : Module
{
protected override void Load(ContainerBuilder containerBuilder)
{
#region 依赖于配置文件配置服务
// 实例化
IConfigurationBuilder config = new ConfigurationBuilder();
//指定配置文件 这里的默认配置文件的路径在根目录下,课根据实际情况调整
config.AddJsonFile("autofac.json");
// Register the ConfigurationModule with Autofac.
IConfigurationRoot configBuild = config.Build();
//读取配置文件里配置需要注册的服务
var module = new ConfigurationModule(configBuild);
containerBuilder.RegisterModule(module);
#endregion
}
}
autofac.json 放在根目录如下:
{
"defaultAssembly": "Microsoft.EntityFrameworkCore", // 抽象所在的程序集名称
"components": [
{
"type": "Shop.EF.Model.shopdbContext,Shop.EF.Model", // 接口的实现类 全名称
"services": [
{
"type": "Microsoft.EntityFrameworkCore.DbContext" // 接口的全名称
}
],
"instanceScope": "single-instance",
"injectProperties": true
},
{
"type": "Shop.Service.BaseService,Shop.Service", // 接口的实现类 全名称
"services": [
{
"type": "Shop.Interface.IBaseService,Shop.Interface" // 接口的全名称
}
],
"instanceScope": "single-instance",
"injectProperties": true
},
{
"type": "Shop.Service.UserService,Shop.Service", // 接口的实现类 全名称
"services": [
{
"type": "Shop.Interface.IUserService,Shop.Interface" // 接口的全名称
}
],
"instanceScope": "single-instance",
"injectProperties": true
},
{
"type": "Shop.Service.ProductService,Shop.Service", // 接口的实现类 全名称
"services": [
{
"type": "Shop.Interface.IProductService,Shop.Interface" // 接口的全名称
}
],
"instanceScope": "single-instance",
"injectProperties": true
},
{
"type": "Shop.Service.OrderService,Shop.Service", // 接口的实现类 全名称
"services": [
{
"type": "Shop.Interface.IOrderService,Shop.Interface" // 接口的全名称
}
],
"instanceScope": "single-instance",
"injectProperties": true
}
]
}