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项目可以说没有多大关联,都可以不知道对方的存在。