(一).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.另一种就是直接在构造方法里面获取,获取后直接赋值给类的成员变量就可以用了

posted @   yingxianqi  阅读(550)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示