在 .NET 中的各个组件之间共享配置设置

发布于 2025-01-03 08:08:16 字数 872 浏览 1 评论 0原文

我知道关于 SO 的类似问题很多,但我有一个警告。

基本前提是可以预见的:我继承了一个由多个组件组成的产品,所有这些组件共享一些配置设置,其中最主要的是连接字符串。目前,这些组件使用散列密码调用 Web 服务,以检索连接字符串 (blegh),但这有时会导致 Windows 启动时 Web 服务和需要配置值的 NT 服务之间出现竞争条件。

我想创建一个优雅的解决方案,允许我从单个安全位置(即注册表或 machine.config)共享这些设置。在给定单一部署环境的情况下,其中任何一个都可以轻松实现,但是(这就是问题所在)其中一个组件是单击一次的应用程序。

简而言之,我的问题是:如何为配置设置创建一个集中机制,并将其传播到一次性部署?

我考虑过的选项:

据我所知,这两种解决方案都依赖于共享配置文件的本地副本的可用性,这不适用于单击一次。

关于单击一次应用程序的部署环境,需要注意两点:

  • 部署始终在公司 LAN 网络内,因此连接字符串等配置设置是普遍适用的。
  • 安装时与单击一次应用程序一起打包的配置设置可以安全地在后续部署中覆盖。

I'm aware that similar questions on SO are numerous, but I have a caveat.

The basic premise is predictable: I inherited a product consisting of several components, all of which share a few configuration settings, connection string chief amongst these. Currently these components call a web service with a hashed password in order to retrieve the connection string (blegh), but this is sometimes causing race conditions at Windows startup between the web serivce and NT services requiring configuration values.

I want to create an elegant solution that allows me to share these settings from a single and secure location, i.e. registry or machine.config. Either one of these would be easily implemented given a single deployment environment, but (here's the problem) one of the components is a click-once application.

So in a nutshell, my question is this: How can I create a centralized mechanism for configuration settings that will also be propagated to click-once deployments?

Options I have considered:

As far as I can tell, both of those solutions depend on the availability of a local copy of a shared config file, which won't work for click-once.

Two things to note about our deployment environment for the click-once application:

  • Deployments are always within a corporate LAN network, thus configuration settings such as the connection string are universally applicable.
  • Configuration settings that are packaged with the click-once application upon installation are safe to be overridden with subsequent deployment.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

私藏温柔 2025-01-10 08:08:16

正如评论中所指出的,我建议当前的解决方案是一个不错的方法,因为网络服务对安全问题不敏感,并且它确保了集中式解决方案。为了克服竞争条件,您可以使用互斥体来强制客户端等待服务器启动。示例代码:

string mutexName = "C01F6FBB-50E9-4BFA-AFBA-209C316AE9FB";
TimeSpan waitInterval = TimeSpan.FromSeconds(1d);

// Server sample
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
    // similate some startup delay for the server
    Thread.Sleep(TimeSpan.FromSeconds(5));

    using (Mutex mutex = new Mutex(true, mutexName))
    {
        Console.WriteLine("Server: Good morning!");

        // Do server business, ensure that the mutex is kept alive throughout the server lifetime
        // this ensures that the application can always check whether the server is available or not
        Thread.Sleep(TimeSpan.FromSeconds(5));    
    }
});

// Application sample
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
    Console.WriteLine("Application: Checking the server...");

    bool mutexOpened = false;

    while (!mutexOpened)
    {
        try
        {
            using (Mutex mutex = Mutex.OpenExisting(mutexName))
            {
                mutexOpened = true;
            }
        }
        catch (WaitHandleCannotBeOpenedException)
        {
            Console.WriteLine("Application: Server is not yet ready....");

            // mutex does not exist yet, wait for the server to boot up
            Thread.Sleep(waitInterval);
        }
    }

    // Server is ready, we can do our application business now
    // note that we dont need to preserve the mutex anymore. 
    // we only used it to ensure that the server is available.
    Console.WriteLine("Application: Good morning to you!");
});

Console.ReadLine();

希望这有帮助!

As indicated in the comments, i would suggest that the current solution is a decent way since webservices are not sensitive to security issue's and it ensures a centralized solution. To overcome the race condition, you can use mutexes to force the client to wait for the server to come up. Example code:

string mutexName = "C01F6FBB-50E9-4BFA-AFBA-209C316AE9FB";
TimeSpan waitInterval = TimeSpan.FromSeconds(1d);

// Server sample
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
    // similate some startup delay for the server
    Thread.Sleep(TimeSpan.FromSeconds(5));

    using (Mutex mutex = new Mutex(true, mutexName))
    {
        Console.WriteLine("Server: Good morning!");

        // Do server business, ensure that the mutex is kept alive throughout the server lifetime
        // this ensures that the application can always check whether the server is available or not
        Thread.Sleep(TimeSpan.FromSeconds(5));    
    }
});

// Application sample
System.Threading.Tasks.Task.Factory.StartNew(() =>
{
    Console.WriteLine("Application: Checking the server...");

    bool mutexOpened = false;

    while (!mutexOpened)
    {
        try
        {
            using (Mutex mutex = Mutex.OpenExisting(mutexName))
            {
                mutexOpened = true;
            }
        }
        catch (WaitHandleCannotBeOpenedException)
        {
            Console.WriteLine("Application: Server is not yet ready....");

            // mutex does not exist yet, wait for the server to boot up
            Thread.Sleep(waitInterval);
        }
    }

    // Server is ready, we can do our application business now
    // note that we dont need to preserve the mutex anymore. 
    // we only used it to ensure that the server is available.
    Console.WriteLine("Application: Good morning to you!");
});

Console.ReadLine();

Hope this helps!

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文