(一).net core依赖注入控制反转(IOC)
对依赖注入的原理是什么,好处是什么进行分析,以及对注入的方式,获取实例的方式(反射获取,构造方法获取)进行分析
1:让容器去实例化对象,在在代码中去直接获取实例化之后的对象,呢种就是依赖注入控制反转IOC思想,好处是不用我们手动去类里面去实例化对象,降低代码的耦合度
2:(autafac容器,.net core自带实例化对象的容器)依赖注入的常见的三种生命周期:
一种是每次请求,获取到的都是同一个实例(core自带容器相当于AddSingleton注入方式;autafac里面相当于SingleInstance注入方式)
一种是每次请求,获取一个实例获取多次,每次获取到的都是同一个实例,第二次请求获取到的就是另一个实例了(core自带容器相当于AddScoped注入方式;autafac里面相当于InstancePerLifetimeScope注入方式)
一种是每次请求,获取一个实例获取多次,每次都获取到的都是不同实例(core自带容器相当于AddTransient注入方式;autafac里面相当于InstancePerDependency注入方式)
3:获取实例的方式:
一种是构造方法获取,
一种是反射获取(快捷获取实例,不用在构造方法获取;在静态类里面我们不能去写对应的构造方法,呢时候只能通过反射获取,因为在静态类里面不能去手动创建构造方法获取实例)
4:autafac在.net core中的运用方式
(1)在nuget引用Autofac,Autofac.Extensions.DependencyInjection,Microsoft.Extensions.DependencyModel
(2)在program.cs里面的CreateHostBuilder方法末尾加 .UseServiceProviderFactory(new AutofacServiceProviderFactory()),表示启用autofac
(3)在Startup.cs里面增加注入的方法(ConfigureContainer呢个方法名称是固定的,不能变)
private IServiceCollection Services { get; set; }定义一个Services成员变量,在ConfigureServices里面实例化: Services = services;
注意下面的AddModule只是ConfigureServices里面的一个拓展方法
public void ConfigureContainer(ContainerBuilder builder)
{
Services.AddModule(builder, Configuration);
}
5:注入逻辑
(1)获取项目所有依赖的程序集,
(2)排除所有的系统程序集和nuget下载包
(3)新建一个类,作为注入类的标识,必须要继承这个类的子类才会被注入,这是最方便控制的一种方式
public static IServiceCollection AddModule(this IServiceCollection services, ContainerBuilder builder, IConfiguration configuration)
{
Type baseType = typeof(IDependency);//注入类的父类标识,只有继承了这个类的子类才会被注入
var compilationLibrary = DependencyContext.Default.CompileLibraries.Where(s=>!s.Serviceable && s.Type == "project").ToList();//排除所有的系统程序集和nuget下载包
List<Assembly> assemblyList = new List<Assembly>();
foreach (var item in compilationLibrary)
{
try
{
assemblyList.Add(AssemblyLoadContext.Default.LoadFromAssemblyName(new AssemblyName(item.Name)));
}
catch (Exception ex)
{
string msg=item.Name + ex.Message;//可以把异常记入log日志
}
}
//AsSelf():类没有继承于接口,类本身;AsImplementedInterfaces():是以接口的形式注册服务,也就是说,通过这种方式注册,那么被注册的类必须要继承于至少一个接口
//InstancePerLifetimeScope相当于在每次HTTP请求中只获取到一个实例;SingleInstance:单例模式,每次请求获取到的都是同一个实例;InstancePerDependency:每次请求,获取多次,会实例化多次(生命周期)
builder.RegisterAssemblyTypes(assemblyList.ToArray()).Where(type=>baseType.IsAssignableFrom(type) && !type.IsAbstract)//注册所有继承IDependency接口的类并且非抽象类
.AsSelf().AsImplementedInterfaces().InstancePerLifetimeScope();
//对具体类的注入
builder.RegisterType<User>().InstancePerLifetimeScope();
//对具体接口的注入
builder.RegisterType<Category>().As<ICategory>().InstancePerLifetimeScope();
return services;
}
6:如何反射获取实例
(1)在Startup里面的ConfigureServices里面注入IHttpContextAccessor
services.AddHttpContextAccessor();
(2):在Startup.cs的Configure方法里面去获取IHttpContextAccessor得实例,以后就用这个IHttpContextAccessor实例得HttpContext属性去反射获取对象
app.UseStaticHttpContext();
(3).新建一个静态类,用来获取IHttpContextAccessor的实例
public static class StaticHttpContextExtensions
{
public static IApplicationBuilder UseStaticHttpContext(this IApplicationBuilder app)
{
var httpContextAccessor = app.ApplicationServices.GetRequiredService<IHttpContextAccessor>();
HttpContext.Configure(httpContextAccessor);
return app;
}
}
(4).在建一个静态类,用来专门获取注入对象的实例
public static class HttpContext
{
private static IHttpContextAccessor _accessor;
public static Microsoft.AspNetCore.Http.HttpContext Current => _accessor.HttpContext;//获取HttpContext的实例
public static void Configure(IHttpContextAccessor accessor)
{
_accessor = accessor;
}
//获取注入对象的实例
public static T GetService<T>()where T :class{
return Current.RequestServices.GetService(typeof(T)) as T;
}
}
7.另一种就是直接在构造方法里面获取,获取后直接赋值给类的成员变量就可以用了
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现