网站首页 网站源码
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.Any()) 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
:定义了一个静态类,包含扩展方法。AddDefaultServices
public 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 的依赖注入容器中。它允许开发者通过配置文件灵活地管理服务的注册,而不需要在代码中硬编码服务的实现。这种方式提高了代码的可维护性和可扩展性。