网站首页 网站源码

using Microsoft.Extensions.DependencyInjection;
// ReSharper disable ClassNeverInstantiated.Local
// ReSharper disable CollectionNeverUpdated.Local
// ReSharper disable UnusedAutoPropertyAccessor.Local
namespace Dpz.Core.Service;
public static class ServiceDependencyInjection
{
public static IServiceCollection AddDefaultServices(
this IServiceCollection services,
IConfiguration configuration)
{
var injectServices = configuration.GetSection("RegisterInject").Get<List<RegisterInject>>();
if (injectServices == null || injectServices.Count == 0)
{
return services;
}
foreach (var injectService in injectServices)
{
if (string.IsNullOrEmpty(injectService.InterfaceAssemblyName))
{
continue;
}
var injectTypes = Assembly.Load(injectService.InterfaceAssemblyName).GetTypes()
.Where(x => x.Namespace == injectService.InterfaceNamespace && x.IsInterface)
.ToList();
if (injectService.Remove is { Count: > 0 })
{
injectTypes = injectTypes
.Where(x => x.FullName != null && !injectService.Remove.Contains(x.FullName)).ToList();
}
if (string.IsNullOrEmpty(injectService.ImplementAssemblyName))
{
continue;
}
var implementAssembly = Assembly.Load(injectService.ImplementAssemblyName).GetTypes()
.Where(x => x.Namespace == injectService.ImplementNamespace && !x.IsAbstract && !x.IsInterface)
.ToList();
foreach (var injectType in injectTypes)
{
var defaultImplementType = implementAssembly.FirstOrDefault(x => injectType.IsAssignableFrom(x));
if (defaultImplementType != null)
{
services.AddScoped(injectType, defaultImplementType);
}
}
if (injectService.Add is { Count: > 0 })
{
foreach (var addService in injectService.Add)
{
var injectType = injectTypes.FirstOrDefault(x => x.FullName == addService.ServiceFullName);
var implementType =
implementAssembly.FirstOrDefault(x => x.FullName == addService.ImplementFullName);
if (injectType == null || implementType == null || !injectType.IsAssignableFrom(implementType))
continue;
switch (addService.Type)
{
case "Transient":
services.AddTransient(injectType, implementType);
break;
case "Singleton":
services.AddSingleton(injectType, implementType);
break;
default:
services.AddScoped(injectType, implementType);
break;
}
}
}
}
return services;
}
private class RegisterInject
{
/// <summary>
/// 接口程序集名称
/// </summary>
public string? InterfaceAssemblyName { get; set; }
/// <summary>
/// 实现程序集名称
/// </summary>
public string? ImplementAssemblyName { get; set; }
/// <summary>
/// 接口命名空间
/// </summary>
public string? InterfaceNamespace { get; set; }
/// <summary>
/// 实现命名空间
/// </summary>
public string? ImplementNamespace { get; set; }
/// <summary>
/// 要移除注册的接口完全限定名
/// </summary>
public List<string>? Remove { get; set; }
/// <summary>
/// 要添加的自定义注入类型
/// </summary>
public List<AddService>? Add { get; set; }
}
private class AddService
{
/// <summary>
/// 注入类型:Transient Scoped(default) Singleton
/// </summary>
public string? Type { get; set; }
/// <summary>
/// 依赖注入服务接口完全限定名
/// </summary>
public string? ServiceFullName { get; set; }
/// <summary>
/// 实现完全限定名
/// </summary>
public string? ImplementFullName { get; set; }
}
}上述代码是一个用于依赖注入的扩展方法,属于 ASP.NET Core 的 IServiceCollection 接口。它的主要功能是根据配置文件中的信息动态注册服务。以下是代码的详细解释:
namespace Dpz.Core.Service:定义了一个命名空间,通常用于组织代码。public static class ServiceDependencyInjection:定义了一个静态类,包含扩展方法。AddDefaultServicespublic static IServiceCollection AddDefaultServices(this IServiceCollection services, IConfiguration configuration):这是一个扩展方法,允许在 IServiceCollection 上调用。它接受一个 IConfiguration 对象,用于读取配置。var injectServices = configuration.GetSection("RegisterInject").Get<List<RegisterInject>>();:从配置中读取名为 RegisterInject 的部分,并将其反序列化为 List<RegisterInject> 类型。injectServices 为空或没有任何元素,方法将直接返回原始的 services 对象。RegisterInject 对象,进行以下操作:InterfaceAssemblyName 和 InterfaceNamespace 加载接口类型。Remove 列表不为空,则从接口类型中移除指定的类型。ImplementAssemblyName 和 ImplementNamespace 加载实现类型。Scoped 生命周期(默认)。services.AddScoped(injectType, defaultImplementType); 进行注册。Add 列表不为空,遍历其中的每个 AddService 对象。ServiceFullName 和 ImplementFullName 查找接口和实现类型。Type 属性的值(Transient、Scoped 或 Singleton)将服务注册到 IServiceCollection 中。RegisterInject:用于存储接口和实现的程序集名称、命名空间、要移除的类型和要添加的自定义服务的信息。AddService:用于存储自定义服务的注入类型、服务的完全限定名和实现的完全限定名。这个代码片段的主要功能是根据配置文件动态地注册服务到 ASP.NET Core 的依赖注入容器中。它允许开发者通过配置文件灵活地管理服务的注册,而不需要在代码中硬编码服务的实现。这种方式提高了代码的可维护性和可扩展性。
