繁体   English   中英

如何将 map 的两个配置注册到 ASP.NET 内核的 DI 注入器中的相同类型

[英]How to register two configurations that map to the same type in DI injector in ASP.NET Core

假设我们有两个连接字符串 - 这只是一个示例,无论我在配置什么,我都在寻找一种更好的方法来实现它 - 在 appSettings.json 文件中:

  "ImportDb": {
    "StringConexao": "data source=server_n1;initial catalog=MyImportDb;user id=SYSDBA;password=masterkey;Charset=UTF8;",
    "BooleanProperty": false
  },
  "MainDb": {
    "StringConexao": "data source=server_n1;initial catalog=MyMainDb;user id=SYSDBA;password=masterkey;Charset=UTF8;",
    "BooleanProperty": false
  },

今天,我解决了映射到 2 种不同类型的问题:

public class DbConfig
{
    public string StringConexao { get; set; }
    public bool BooleanProperty { get; set; }
}

public class LocalDbConfig: DbConfig
{

}

并像这样在 DI 中注册:

serviceCollection.Configure<DbConfig>(DadosConfig.GetSection("MainDb"));
serviceCollection.Configure<LocalDbConfig>(DadosConfig.GetSection("ImportDb"));

为什么我这样解决:

  • 两种配置具有完全相同的属性。 它们仅在使用哪个 class 上有所不同。
  • 在上述字符串连接的情况下,这两个配置甚至可以引用两个不同网络上的不同服务器。
  • 我不能将它们视为一个列表(我需要能够在构造函数上解决一个或另一个)

它有一些缺点:

  • 由于这两种类型是后代,如果某些要求发生变化并且使用其中一种配置的 class 也需要接受另一种配置,我不能为每种类型的 DbConfig 分别设置两个构造函数 - 它会混淆 DI 注入器。

所以我问:有一种更“优雅”的方式来进行这种映射吗?

免责声明:

  • user id=SYSDBA;password=masterkey是 FirebirdSQL 数据库服务器的默认登录名/密码。 多年来众所周知。
  • 对于那些好奇的人来说,“StringConexao”的意思是“ConnectionString”。

我尝试创建一个 someservicefactory 来创建具有不同配置的服务,如下所示:

public interface IDbconfig
    {
        public string StringConexao { get; set; }
        public bool BooleanProperty { get; set; }
    }
    public class DbConfig: IDbconfig
    {
        public string StringConexao { get; set; }
        public bool BooleanProperty { get; set; }
    }
    public interface IService
    {
         public string Test { get; set; }
         public string Test1 { get; set; }
    }
    public class Service: IService
    {
        public string Test { get; set; }
        public string Test1 { get; set; }
        public Service(List<DbConfig> config)
        {
            this.Test = config.First().StringConexao;
            this.Test1 = config.Last().StringConexao;
        }
    }
    public interface IServiceFactory
    {
        IServiceFactory Add(string key);
        IService Create(string key);
    }
    public class ServiceFactory : IServiceFactory
    {
       
        private readonly IConfiguration _configuration;
        private readonly Dictionary<string, IService> _someservices = new Dictionary<string, IService>();

        public ServiceFactory(IConfiguration configuration)
        {           
            _configuration = configuration;
            this.Add ("MainDb").Add("ImportDb").Add("MainDb,ImportDb");
        }

        public IServiceFactory Add(string key)
        {
            var keystringlist = key.Split(",").ToList();
            var configs = new List<DbConfig>();
            foreach(var newkey in keystringlist)
            {
                var config = new DbConfig();
                _configuration.GetSection(newkey).Bind(config);
                configs.Add(config);
            }
            var someservice = new Service(configs);
            _someservices.Add(key, someservice);
            return this;
        }
        public IService Create(string keyOfConfiguration)
        {
            return _someservices[keyOfConfiguration];
        }
    }

在startup.cs中:

services.AddSingleton<IServiceFactory, ServiceFactory>();

将工厂注入 controller 或其他地方,并使用不同的配置创建服务:

            var service1 = _serviceFactory.Create("ImportDb");
            var service2 = _serviceFactory.Create("MainDb");
            var service3 = _serviceFactory.Create("MainDb,ImportDb");

结果:

在此处输入图像描述 在此处输入图像描述

您说列表不行,因为您需要在构造函数中处理正确的数据库,但您可以使用字典。 您可以定义一个 class DbConfigs:

public class DBConfigs
{
    public Dictionary<string, DBConfig> DBConfigurations { get; set; }
}

然后在 apSettings 你可以有:

"DBConfigs": {
    "DBConfigurations": {
        "ImportDb": {
            "StringConexao": "data source=server_n1;initial catalog=MyImportDb;user id=SYSDBA;password=masterkey;Charset=UTF8;",
            "BooleanProperty": false
         },
         "MainDb": {
             "StringConexao": "data source=server_n1;initial catalog=MyMainDb;user id=SYSDBA;password=masterkey;Charset=UTF8;",
             "BooleanProperty": false
         }
     }
 }

在 DI 中的注册变为:

serviceCollection.Configure<DbConfigs>(DadosConfig.GetSection("DBConfigs"));

最后,您可以用这种方式扭曲您的构造函数:

public MyClass(DBConfig aConfig)
{
    _myConfig = aConfig.DBConfigurations["MainDB"];
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM