C# .NET如何自动实现依赖注入(DI)
为解决重复性的工作,自动实现依赖注入(DI)
示例代码如下
namespace DialysisSOPSystem.Infrastructure
{public static class ServiceCollectionExtensions{/// <summary>/// 批量注入服务/// </summary>/// <param name="services"></param>/// <returns></returns>public static IServiceCollection RegisterAutoInjectServices(this IServiceCollection services){ArgumentNullException.ThrowIfNull(services);//获取当前Host运行依赖的程序集var context = DependencyContext.Default;var assemblies = context.RuntimeLibraries.SelectMany(lib => lib.GetDefaultAssemblyNames(context)).Select(Assembly.Load).ToList();services.Scan(scan => scan.FromAssemblies(assemblies).AddClasses(classes => classes.AssignableTo<ITransientDependency>()).AsImplementedInterfaces().WithTransientLifetime().AddClasses(classes => classes.AssignableTo<IScopedDependency>()).AsImplementedInterfaces().WithScopedLifetime().AddClasses(classes => classes.AssignableTo<ISingletonDependency>()).AsImplementedInterfaces().WithSingletonLifetime());return services;}}
}
namespace DialysisSOPSystem.Infrastructure
{public interface ITransientDependency { }public interface IScopedDependency { }public interface ISingletonDependency { }
}//1、Transient(瞬态):每次从容器 (IServiceProvider)中获取的时候都是一个新的实例//2、Singleton(单例):每次从同根容器中(同根 IServiceProvider)获取的时候都是同一个实例//3、Scoped(应用程序域单例):每次从同一个容器中获取的实例是相同的、
Startup类
public void ConfigureServices(IServiceCollection services)
{services.RegisterAutoInjectServices();// 添加控制器services.AddControllers();// 添加Swaggerservices.AddEndpointsApiExplorer();services.AddSwaggerGen(c =>{c.SwaggerDoc("v1", new() { Title = "Dialysis SOP API", Version = "v1" });});// 添加AutoMapperservices.AddAutoMapper(typeof(Startup).Assembly);
}
web 项目引用关系如下
//这段代码获取程序集,上面的web引用service和接口、仓储var context = DependencyContext.Default;var assemblies = context.RuntimeLibraries.SelectMany(lib => lib.GetDefaultAssemblyNames(context)).Select(Assembly.Load).ToList();//只能拿到当前所在的类库下的程序集
//var assemblies = AppDomain.CurrentDomain.GetAssemblies();
//或者显示引用,就不在web把其他依赖项拉进去// 从指定路径加载程序集
var assemblyPath = Path.Combine(AppContext.BaseDirectory, "YourProject.Services.dll");
var serviceAssembly = Assembly.LoadFrom(assemblyPath);
// 添加到 DI 扫描范围
var assemblies = new[] { serviceAssembly }.Concat(AppDomain.CurrentDomain.GetAssemblies());