在多个 .NET 应用程序中引用相同的连接字符串
Reference same Connection String in Multiple .NET Applications
我不确定这是否是这个问题的正确媒介,所以如果不是,请通知我,我会更正。
举个例子来说明我的观点,假设我有 30 个 .NET 应用程序发布到 2-3 个不同的 Web 服务器。现在,这些应用程序是基于 Intranet 的,因此我在每个应用程序中都引用了一个 C# 库。该库由我在每个应用程序中使用的方法组成,以便在必要时查找员工信息。现在,库有一个连接字符串,但我还必须在所有 30 个应用程序中引用相同的连接字符串...所以如果库引用的数据库发生变化,那么我必须记住所有 30 个应用程序并更改他们每个人。
有没有办法将连接字符串放在某种文件(文本文件或其他文件)中,并让 30 个应用程序中的每个 web.config 都引用该特定文件,所以如果连接string需要改,我直接在文件里改,然后30个应用都还可以,还是没有这样的?
更新
好的,我现在知道如何为连接字符串目的引用文本文件了。但是,似乎我只能做两个选项之一...要么在 web.config 中分别引用我的主连接字符串和库连接字符串,如下所示:
选项一
<connectionStrings>
<add name="PrimaryCS" // more data />
<add name="LibraryCS" // more data />
</connectionStrings>
这个选项将要求我在 30 个应用程序中的每个应用程序中更改 LibraryCS
连接字符串,如果它曾经被更改的话(这不是我想要的)
选项二
<connectionStrings configSource="MyConfig.config"></connectionStrings>
此选项强制我将两个连接字符串都放在 MyConfig.config
文件中,而不仅仅是 LibraryCS
文件..所以这将导致我不得不更改 LibraryCS
30 个应用程序的每个 MyConfig.config
文件中的连接字符串(同样,这不是我想要的)。
我在找什么
我正在寻找这两种选择的混合体,但似乎无法做到,所以我希望这个媒体上的人知道解决方法
<connectionStrings configSource="MyConfig.config">
<add name="PrimaryCS" // more data />
</connectionStrings>
我希望 MyConfig.config
文件只保存 LibraryCS
连接字符串,然后将主 PrimaryCS
连接字符串分开..这样如果LibraryCS
曾经需要更改连接字符串,那么我只需在一个地方进行。
我想到的一个解决方案是创建一个共享连接字符串文件并在多个 Web 应用程序项目的 web.config 中引用它。
所以在我的网络配置中我有这个:
<connectionStrings configSource="configs\connectionStrings.local.config">
此文件仅包含配置的 'connectionStrings' 部分。
然后我将 connectionStrings.local.config 文件从公共解决方案文件夹复制到项目构建时的 configs 文件夹中(配置文件作为解决方案项添加到解决方案中。
其他替代方法是在服务器上使用环境变量来存储连接字符串,或者像人们提到的普通文件一样(只需像读取任何文本文件一样读取文件)。
一个绝妙的解决方案是在其他项目中添加配置文件快捷方式,这样您只需更新一个文件:
它类似于共享程序集文件(在答案 #2 中演示:)
如果您需要更多环境,请使用转换:
我知道这是一个简短的回答,我喜欢真正简单的解决方案。如果您有任何问题,请告诉我。
Microsoft 有关于它的精彩文档。希望对您有所帮助。
To store connection strings in an external configuration file, create
a separate file that contains only the connectionStrings section. Do
not include any additional elements, sections, or attributes. This
example shows the syntax for an external configuration file.
<connectionStrings>
<add name="Name"
providerName="System.Data.ProviderName"
connectionString="Valid Connection String;" />
</connectionStrings>
In the main application configuration file, you use the configSource
attribute to specify the fully qualified name and location of the
external file. This example refers to an external configuration file
named connections.config.
<?xml version='1.0' encoding='utf-8'?>
<configuration>
<connectionStrings configSource="connections.config"/>
</configuration>
不知道这是否是您要搜索的内容,但是当您重载 ApplicationDbContext 的构造函数时,您可以指定它应该使用哪个连接字符串:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext() : base(GetConnectionStringName(), throwIfV1Schema: false)
{
}
static string GetConnectionStringName()
{
// Your logic for the connectionstring, I use the Request.Url here.
return HttpContext.Current.Request.Url.Authority.ToLower().Split(new char[] { ':' }).FirstOrDefault().Replace("www.", "");
}
}
您是否考虑过使用 Apache Zookeeper?您的用例似乎符合其定义:
ZooKeeper is a centralized service for maintaining configuration information...
您可以在某处启动一个 ZooKeeper 实例并在其中保存您的配置设置。您的设置将以类似于文件系统结构的结构进行组织。它可能看起来像这样(使用 ZooKeeper 附带的 zkCli.sh
创建配置,例如):
create /common-settings
create /common-settings/connectionString 1.1.1.1:123
...
create /app-1-settings
create /app-1-settings/app-specific-setting myArbitrarySetting
然后您可以设置您的应用程序以包含 ZooKeeper 客户端,以便它们能够读取您存储的配置。对于 .NET,我找到了 https://github.com/shayhatsor/zookeeper, which seems to meticulously mimic the Java client: https://github.com/ewhauser/zookeeper。
我没有广泛使用它,但我得到了以下工作(注意 C# 7.1+,由于 async Main()):
using System;
using System.Text;
using System.Threading.Tasks;
using org.apache.zookeeper; // NuGet: ZooKeeperNetEx
namespace Example
{
// Watcher will notify us of events we get from ZooKeeper
class MyWatcher : Watcher
{
public override async Task process(WatchedEvent @event)
{
Console.WriteLine($"Process event: {@event}");
}
}
class Program
{
async static Task Main()
{
// Create a new ZK client.
var zookeeper = new ZooKeeper("<zookeeper-url>", sessionTimeout: 3000, new MyWatcher());
// Use it to request a config setting.
var connectionData = await zookeeper.getDataAsync("/common-settings/connectionString");
// Convert the received data from bytes to string.
var connectionString = Encoding.UTF8.GetString(connectionData.Data);
Console.WriteLine($"Got connectionString '{connectionString}'."); // Got connectionString '1.1.1.1:123'
Console.Read();
}
}
}
我相信您可以不费吹灰之力就可以根据自己的具体需求调整它。
要开始使用 ZooKeeper,您可以查看他们的 Getting Started.
当然,网上也有很多信息。
我不确定这是否是这个问题的正确媒介,所以如果不是,请通知我,我会更正。
举个例子来说明我的观点,假设我有 30 个 .NET 应用程序发布到 2-3 个不同的 Web 服务器。现在,这些应用程序是基于 Intranet 的,因此我在每个应用程序中都引用了一个 C# 库。该库由我在每个应用程序中使用的方法组成,以便在必要时查找员工信息。现在,库有一个连接字符串,但我还必须在所有 30 个应用程序中引用相同的连接字符串...所以如果库引用的数据库发生变化,那么我必须记住所有 30 个应用程序并更改他们每个人。
有没有办法将连接字符串放在某种文件(文本文件或其他文件)中,并让 30 个应用程序中的每个 web.config 都引用该特定文件,所以如果连接string需要改,我直接在文件里改,然后30个应用都还可以,还是没有这样的?
更新
好的,我现在知道如何为连接字符串目的引用文本文件了。但是,似乎我只能做两个选项之一...要么在 web.config 中分别引用我的主连接字符串和库连接字符串,如下所示:
选项一
<connectionStrings>
<add name="PrimaryCS" // more data />
<add name="LibraryCS" // more data />
</connectionStrings>
这个选项将要求我在 30 个应用程序中的每个应用程序中更改 LibraryCS
连接字符串,如果它曾经被更改的话(这不是我想要的)
选项二
<connectionStrings configSource="MyConfig.config"></connectionStrings>
此选项强制我将两个连接字符串都放在 MyConfig.config
文件中,而不仅仅是 LibraryCS
文件..所以这将导致我不得不更改 LibraryCS
30 个应用程序的每个 MyConfig.config
文件中的连接字符串(同样,这不是我想要的)。
我在找什么
我正在寻找这两种选择的混合体,但似乎无法做到,所以我希望这个媒体上的人知道解决方法
<connectionStrings configSource="MyConfig.config">
<add name="PrimaryCS" // more data />
</connectionStrings>
我希望 MyConfig.config
文件只保存 LibraryCS
连接字符串,然后将主 PrimaryCS
连接字符串分开..这样如果LibraryCS
曾经需要更改连接字符串,那么我只需在一个地方进行。
我想到的一个解决方案是创建一个共享连接字符串文件并在多个 Web 应用程序项目的 web.config 中引用它。
所以在我的网络配置中我有这个:
<connectionStrings configSource="configs\connectionStrings.local.config">
此文件仅包含配置的 'connectionStrings' 部分。
然后我将 connectionStrings.local.config 文件从公共解决方案文件夹复制到项目构建时的 configs 文件夹中(配置文件作为解决方案项添加到解决方案中。
其他替代方法是在服务器上使用环境变量来存储连接字符串,或者像人们提到的普通文件一样(只需像读取任何文本文件一样读取文件)。
一个绝妙的解决方案是在其他项目中添加配置文件快捷方式,这样您只需更新一个文件:
它类似于共享程序集文件(在答案 #2 中演示:)
如果您需要更多环境,请使用转换:
我知道这是一个简短的回答,我喜欢真正简单的解决方案。如果您有任何问题,请告诉我。
Microsoft 有关于它的精彩文档。希望对您有所帮助。
To store connection strings in an external configuration file, create a separate file that contains only the connectionStrings section. Do not include any additional elements, sections, or attributes. This example shows the syntax for an external configuration file.
<connectionStrings>
<add name="Name"
providerName="System.Data.ProviderName"
connectionString="Valid Connection String;" />
</connectionStrings>
In the main application configuration file, you use the configSource attribute to specify the fully qualified name and location of the external file. This example refers to an external configuration file named connections.config.
<?xml version='1.0' encoding='utf-8'?>
<configuration>
<connectionStrings configSource="connections.config"/>
</configuration>
不知道这是否是您要搜索的内容,但是当您重载 ApplicationDbContext 的构造函数时,您可以指定它应该使用哪个连接字符串:
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext() : base(GetConnectionStringName(), throwIfV1Schema: false)
{
}
static string GetConnectionStringName()
{
// Your logic for the connectionstring, I use the Request.Url here.
return HttpContext.Current.Request.Url.Authority.ToLower().Split(new char[] { ':' }).FirstOrDefault().Replace("www.", "");
}
}
您是否考虑过使用 Apache Zookeeper?您的用例似乎符合其定义:
ZooKeeper is a centralized service for maintaining configuration information...
您可以在某处启动一个 ZooKeeper 实例并在其中保存您的配置设置。您的设置将以类似于文件系统结构的结构进行组织。它可能看起来像这样(使用 ZooKeeper 附带的 zkCli.sh
创建配置,例如):
create /common-settings
create /common-settings/connectionString 1.1.1.1:123
...
create /app-1-settings
create /app-1-settings/app-specific-setting myArbitrarySetting
然后您可以设置您的应用程序以包含 ZooKeeper 客户端,以便它们能够读取您存储的配置。对于 .NET,我找到了 https://github.com/shayhatsor/zookeeper, which seems to meticulously mimic the Java client: https://github.com/ewhauser/zookeeper。
我没有广泛使用它,但我得到了以下工作(注意 C# 7.1+,由于 async Main()):
using System;
using System.Text;
using System.Threading.Tasks;
using org.apache.zookeeper; // NuGet: ZooKeeperNetEx
namespace Example
{
// Watcher will notify us of events we get from ZooKeeper
class MyWatcher : Watcher
{
public override async Task process(WatchedEvent @event)
{
Console.WriteLine($"Process event: {@event}");
}
}
class Program
{
async static Task Main()
{
// Create a new ZK client.
var zookeeper = new ZooKeeper("<zookeeper-url>", sessionTimeout: 3000, new MyWatcher());
// Use it to request a config setting.
var connectionData = await zookeeper.getDataAsync("/common-settings/connectionString");
// Convert the received data from bytes to string.
var connectionString = Encoding.UTF8.GetString(connectionData.Data);
Console.WriteLine($"Got connectionString '{connectionString}'."); // Got connectionString '1.1.1.1:123'
Console.Read();
}
}
}
我相信您可以不费吹灰之力就可以根据自己的具体需求调整它。
要开始使用 ZooKeeper,您可以查看他们的 Getting Started.
当然,网上也有很多信息。