注册多个服务的最优方式是什么?如何避免重复注册多个自定义Manager?
自定义Manager类服务注册最优实现方案
批量扫描自动注册(最优方案,完全避免重复注册代码)
这是最适合多同类Manager注册的方案,核心逻辑是通过反射扫描符合约定的Manager类,自动完成注册,后续新增Manager无需修改注册代码:
- 第一步:定义统一约定(二选一即可)
- 定义空标记接口:所有自定义Manager实现
IManager空接口,用于扫描时精准匹配 - 统一继承基类:如果所有Manager都继承自同一个通用基类(如
BaseManager),直接用基类作为扫描判断条件
- 定义空标记接口:所有自定义Manager实现
- 第二步:编写IServiceCollection扩展方法封装注册逻辑
示例代码(以标记接口为例):public static class ManagerServiceExtensions { public static IServiceCollection AddAllCustomManagers(this IServiceCollection services) { // 扫描指定程序集中符合要求的Manager类 var managerTypes = Assembly.GetExecutingAssembly() .GetTypes() .Where(t => typeof(IManager).IsAssignableFrom(t) && t.IsClass && !t.IsAbstract ); foreach (var implType in managerTypes) { // 支持按接口注册(如IOrderManager对应OrderManager),无匹配接口则注册自身类型 var serviceType = implType.GetInterfaces().FirstOrDefault(i => i.Name == $"I{implType.Name}") ?? implType; // 默认用Scoped生命周期,和Identity.UserManager保持一致 services.AddScoped(serviceType, implType); } return services; } } - 第三步:在Program.cs中一行完成所有Manager注册
builder.Services.AddAllCustomManagers();
扩展适配场景
如果不同Manager需要不同的生命周期,可以通过自定义属性实现灵活配置:
- 定义生命周期标记属性
[AttributeUsage(AttributeTargets.Class)] public class ManagerLifetimeAttribute : Attribute { public ServiceLifetime Lifetime { get; } public ManagerLifetimeAttribute(ServiceLifetime lifetime) { Lifetime = lifetime; } }
- 给Manager类标记对应生命周期
[ManagerLifetime(ServiceLifetime.Singleton)] public class AppConfigManager : IManager { // 业务逻辑 }
- 修改注册逻辑,读取属性配置生命周期即可
var lifetimeAttr = implType.GetCustomAttribute<ManagerLifetimeAttribute>(); var lifetime = lifetimeAttr?.Lifetime ?? ServiceLifetime.Scoped; services.Add(new ServiceDescriptor(serviceType, implType, lifetime));
轻量场景备选方案
如果Manager数量很少(少于5个),也可以把所有手动注册逻辑封装到同一个扩展方法中,虽然还是手动注册,但避免了注册逻辑散落在Program.cs各处,也便于统一维护。
内容的提问来源于stack exchange,提问作者Mohammadreza Askari
相关产品推荐
相关产品推荐

