首先,Nicholi的回答给了我灵感!谢谢你,Nicholi。
其次,我提供了一个“列表”解决方案,而不是IDictionary解决方案。它不像IDictionary解决方案那样流畅。
这也可以被称为“如何为dot net core配置创建集合列表”
接下来是具体步骤:
首先,无耻地进行一次抄袭!
public class ConnectionStringEntry
{
public String Name { get; set; }
public String ConnectionString { get; set; }
public String ProviderName { get; set; }
public ConnectionStringEntry()
{
}
public ConnectionStringEntry(String name, String connectionString)
: this(name, connectionString, null)
{
}
public ConnectionStringEntry(String name, String connectionString, String providerName)
{
this.Name = name;
this.ConnectionString = connectionString;
this.ProviderName = providerName;
}
}
第二,一个“包装器”。我想在我的条目列表(集合)旁边跟踪DefaultConnectionStringName...。
public class ConnectionStringWrapper
{
public string DefaultConnectionStringName { get; set; } = "";
public List<ConnectionStringEntry> ConnectionStringEntries { get; set; } = new List<ConnectionStringEntry>();
public ConnectionStringEntry GetDefaultConnectionStringEntry()
{
ConnectionStringEntry returnItem = this.GetConnectionStringEntry(this.DefaultConnectionStringName);
return returnItem;
}
public ConnectionStringEntry GetConnectionStringEntry(string name)
{
ConnectionStringEntry returnItem = null;
if (null != this.ConnectionStringEntries && this.ConnectionStringEntries.Any())
{
returnItem = this.ConnectionStringEntries.FirstOrDefault(ce => ce.Name.Equals(name, StringComparison.OrdinalIgnoreCase));
}
if (null == returnItem)
{
throw new ArgumentOutOfRangeException(string.Format("No default ConnectionStringEntry found. (ConnectionStringEntries.Names='{0}', Search.Name='{1}')", this.ConnectionStringEntries == null ? string.Empty : string.Join(",", this.ConnectionStringEntries.Select(ce => ce.Name)), name));
}
return returnItem;
}
}
现在,我正在阅读json并将其映射到一个具体的设置对象代码:
IConfiguration config = new ConfigurationBuilder()
.SetBasePath(System.IO.Directory.GetCurrentDirectory())
.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
.Build();
ConnectionStringWrapper settings = new ConnectionStringWrapper();
config.Bind("ConnectionStringWrapperSettings", settings);
Console.WriteLine("{0}, {1}", settings.DefaultConnectionStringName, settings.ConnectionStringEntries.Count);
ConnectionStringEntry cse = settings.GetDefaultConnectionStringEntry();
我的NuGet包:
\.nuget\packages\microsoft.extensions.configuration\2.1.1
\.nuget\packages\microsoft.extensions.configuration.binder\2.1.1
\.nuget\packages\microsoft.extensions.configuration.json\2.1.1
以下是奖励材料:
为了支持可以部署为DotNet 4.x(“经典”?现在这个术语?)和dotnet core的代码库,我正在尝试做的一件事情之一是提供一个抽象,使得从DotNet(经典)处理连接字符串(xml,我们老朋友)到新的酷玩具:使用json的DotNetCore更加容易。
为此,我编写了一个接口:
public interface IConnectionStringWrapperRetriever
{
ConnectionStringWrapper RetrieveConnectionStringWrapper();
}
我有一个针对dotnetcore的实现:
public class ConnectionStringWrapperDotNetCoreRetriever : IConnectionStringWrapperRetriever
{
public const string ConnectionStringWrapperSettingsJsonElementName = "ConnectionStringWrapperSettings";
private readonly IConfiguration config;
public ConnectionStringWrapperDotNetCoreRetriever(IConfiguration cnfg)
{
this.config = cnfg;
}
public ConnectionStringWrapper RetrieveConnectionStringWrapper()
{
ConnectionStringWrapper settings = new ConnectionStringWrapper();
this.config.Bind(ConnectionStringWrapperSettingsJsonElementName, settings);
return settings;
}
}
哦,是的,非常重要的JSON设置:
{
"ConnectionStringWrapperSettings": {
"DefaultConnectionStringName": "abc",
"ConnectionStringEntries": [
{
"Name": "abc",
"ConnectionString": "Server=myserver;Database=mydatabase;Trusted_Connection=True;MultipleActiveResultSets=true",
"ProviderName": "SomeProvider"
},
{
"Name": "def",
"ConnectionString": "server=localhost;database=db2;username=user2;password=pass2;",
"ProviderName": "SomeProvider"
}
]
}
}
对于DotNet(经典版),您只需要实现第二个IConnectionStringWrapperRetriever的具体内容,并进行魔法操作即可。
还记得下面的xml吗?(哈哈,它还没有那么老!)
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<connectionStrings>
<add name="ConnStr1" connectionString="LocalSqlServer: data source=127.0.0.1;Integrated Security=SSPI;Initial Catalog=aspnetdb"
providerName="System.Data.SqlClient" />
</connectionStrings>
</configuration>
(来自https://learn.microsoft.com/en-us/dotnet/api/system.configuration.connectionstringsettingscollection?view=netframework-4.7.2)
还记得EnterpriseLibrary中的这些内容吗?
<configSections>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"/>
</configSections>
<dataConfiguration defaultDatabase="ConnStr1"/>
我将DotNet(Classic)的实现留给读者自己完成。
现在,我将IConnectionStringWrapperRetriever注入到我的DataLayer类中。
我正在使用Dapper,所以我可以使用IConnectionStringWrapperRetriever来获取连接字符串。
如果我的项目是“house” DotNet(Classic),我注入一个版本的IConnectionStringWrapperRetriever(这里未显示,留给读者自己完成)。如果我的项目是“housed”在DotNetCore中,我注入第二个(如上所示)版本的IConnectionStringWrapperRetriever。
超出了本篇文章的范围,但是我所说的“housed”是指我有两个csproj并排放置。
MyApp.DataLayer.classic.csproj
和
MyApp.DataLayer.csproj
我发现将默认的csproj用于承载DotNetCore相关内容更容易一些。我使用“classic.csproj”文件来承载DotNet(classic)相关内容。我的程序集名称和默认命名空间仍为“MyApp.Datalayer”...... .classic仅用于csrproj文件名以区分。
我还创建了两个解决方案sln文件。MySolution.classic.sln和MySolution.sln。
看起来它正在工作......使用我上面编写的ConnectionString抽象。
我唯一的条件是在(classic)AssemblyInfo.cs文件上。
#if(!NETCOREAPP2_1)
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]
#endif
追加:
好的,这是DotNet(经典版)的版本:
public class ConnectionStringWrapperDotNetClassicRetriever : IConnectionStringWrapperRetriever
{
public ConnectionStringWrapper RetrieveConnectionStringWrapper()
{
ConnectionStringWrapper returnItem = new ConnectionStringWrapper();
foreach(ConnectionStringSettings css in System.Configuration.ConfigurationManager.ConnectionStrings)
{
ConnectionStringEntry cse = new ConnectionStringEntry(css.Name, css.ConnectionString, css.ProviderName);
returnItem.ConnectionStringEntries.Add(cse);
}
if(returnItem.ConnectionStringEntries.Count == 1)
{
returnItem.DefaultConnectionStringName = returnItem.ConnectionStringEntries.First().Name;
}
else
{
DatabaseSettings dbSettings = (DatabaseSettings)ConfigurationManager.GetSection("dataConfiguration");
returnItem.DefaultConnectionStringName = dbSettings.DefaultDatabase;
}
return returnItem;
}
}
还有app.config xml文件:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data"/>
</configSections>
<connectionStrings>
<clear/>
<add name="MyFirstConnectionStringName" connectionString="Server=.\MyServerOne;Database=OneDB;Trusted_Connection=True;MultipleActiveResultSets=true"
providerName="System.Data.SqlClient" />
<add name="MySecondConnectionStringName" connectionString="Server=.\MyServerTwo;Database=TwoDB;Trusted_Connection=True;MultipleActiveResultSets=true"
providerName="System.Data.SqlClient" />
</connectionStrings>
<dataConfiguration defaultDatabase="MyFirstConnectionStringName" />
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
</configuration>
关键词:
DotNet DotNet .Net Core Classic Json配置 ICollection 标量和集合支持dotnet和dotnetcore