asp.net core通过配置决定AddSingleton的实现类

有一些接口,我们也不知道最终谁来实现, 又或者不同的环境有不同的实现。于是我们希望通过配置来处理。

//通过配置决定实际注入类
builder.Services.AddSingletonIfCfg<ISmsVerifyCodeService>(builder.Configuration, "SmsVerifyCodeService:TypeName");

那我们只需在appsetting.json中修改,以使用不同实现。下面注入的是:SmsAdapter.AliyunSMSVerifyCodeService, SmsAdapter

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "SmsVerifyCodeService": {
    "TypeName": "SmsAdapter.AliyunSMSVerifyCodeService, SmsAdapter",
    "Aliyun": {"AccessId": "yyyyyy",
      "AccessSecret": "bbbb",      
      "SignName": "myapp",
      "TemplateCode": "SMS_222"
    }    
  }
}
具体的AddSingletonIfCfg方法在以下静态工具类提供
public static class DynamicServiceFactory
{
    public static void AddSingletonIfCfg<T>(this IServiceCollection services, IConfiguration config, string configKey)
    {
        var typeName = config.GetValue<string>(configKey);
        if (string.IsNullOrEmpty(typeName))
        {
            Console.WriteLine($" AddSingletonIfCfg miss configKey: {configKey} .");
            return;
        }

        var type = Type.GetType(typeName);
        if (type == null)
            throw new Exception($" AddSingletonIfCfg miss typeName: {typeName} .");
        if (!typeof(T).IsAssignableFrom(type))
            throw new Exception($" AddSingletonIfCfg typeName: {typeName} not implement {typeof(T).FullName} .");
        // 使用ActivatorUtilities创建实例并注册服务
        services.AddSingleton(typeof(T), serviceProvider =>
        {
            try
            {
                return ActivatorUtilities.CreateInstance(serviceProvider, type);
            }
            catch (Exception ex)
            {
                throw new Exception($"Failed to create instance of type {typeName}.", ex);
            }
        });
    }
}

好了,我们就可以增加一个类库项目SmsAdapter,一个类AliyunSMSVerifyCodeService来实现ISmsVerifyCodeService。

AliyunSMSVerifyCodeService类可以象在主程序中一样书写,可以使用注入的所有服务。

另外,一般来说ISmsVerifyCodeService定义在基础类库,就是asp.net core主程序和SmsAdapter项目都会引用的项目。而主程序和SmsAdapter项目可以说没有多大关联,都可以不知道对方的存在。

 

 

 



 

posted @ 2025-09-30 16:22  生命体验之kevin-Y  阅读(3)  评论(0)    收藏  举报