1

我们正在开发旧版 C# 企业应用程序。它的客户端使用多个 Web 服务,其 URL 以及许多其他设置都是从​​本地 app.config 文件中读取的。我们希望将这些设置迁移到全局数据库中以简化它们的管理。但是,我无法弄清楚如何(以及是否)可以迁移 Web 服务 URL。这些是从 VS 生成的服务客户端代码中读取的,我似乎无法找到一种方法来告诉 VS 使用与生成的设置提供程序不同的设置提供程序Settings.Designer.cs

我们可以在创建后用我们想要的值覆盖服务外观的Url属性——这是目前在代码中的几个地方使用的解决方案。但是,我不想触及我们代码库中使用任何这些服务的每个部分(现在和将来)。我更不想修改生成的代码。

必须有一个更好、更清洁、更安全的解决方案——或者有吗?

顺便说一句,我们的应用程序在 .NET 2.0 上运行,在可预见的将来我们不会迁移到更新版本的平台。

4

1 回答 1

1

Visual Studio 生成的Refernce.cs文件指示将从设置中检索 Web 服务的 URL:

this.Url = global::ConsoleApplication1.Properties.
    Settings.Default.ConsoleApplication1_net_webservicex_www_BarCode;

我相信约翰桑德斯在他的评论中给了你一个很好的建议。你需要一个SettingsProvider

...定义了用于存储应用程序设置架构中使用的配置数据的机制。.NET Framework 包含一个默认设置提供程序 LocalFileSettingsProvider,它将配置数据存储到本地文件系统。但是,您可以通过从抽象 SettingsProvider 类派生来创建备用存储机制。包装类使用的提供者是通过使用 SettingsProviderAttribute 装饰包装类来确定的。如果未提供此属性,则使用默认值 LocalFileSettingsProvider。

我不知道您采用这种方法取得了多大的进步,但它应该非常简单:

  1. 创建SettingsProvider类:

    namespace MySettings.Providers
    {
        Dictionary<string, object> _mySettings;
    
        class MySettingsProvider : SettingsProvider
        {
            // Implement the constructor, override Name, Initialize, 
            // ApplicationName, SetPropertyValues and GetPropertyValues (see step 3 below)
            // 
            // In the constructor, you probably might want to initialize the _mySettings 
            // dictionary and load the custom configuration into it.
            // Probably you don't want make calls to the database each time
            // you want to read a setting's value
        }
    }
    
  2. 扩展项目分部类的类定义YourProjectName.Properties.Settings并用SettingsProviderAttribute:

    [System.Configuration.SettingsProvider(typeof(MySettings.Providers.MySettingsProvider))]
    internal sealed partial class Settings
    {
        //
    }
    
  3. 在覆盖GetPropertyValues方法中,您必须从_mySettings字典中获取映射值:

    public override SettingsPropertyValueCollection GetPropertyValues(
        SettingsContext context,
        SettingsPropertyCollection collection)
    {
        var spvc = new SettingsPropertyValueCollection();
        foreach (SettingsProperty item in collection)
        {
            var sp = new SettingsProperty(item);
            var spv = new SettingsPropertyValue(item);
            spv.SerializedValue = _mySettings[item.Name];
            spv.PropertyValue = _mySettings[item.Name];
            spvc.Add(spv);
        }
        return spvc;
    }
    

正如您在代码中看到的那样,为了做到这一点,您需要知道添加到 Web 服务 ( )的引用时添加app.config的设置名称:Settings.settingsConsoleApplication1_net_webservicex_www_BarCode

<applicationSettings>
    <ConsoleApplication30.Properties.Settings>
        <setting name="ConsoleApplication1_net_webservicex_www_BarCode"
            serializeAs="String">
            <value>http://www.webservicex.net/genericbarcode.asmx</value>
        </setting>
    </ConsoleApplication30.Properties.Settings>
</applicationSettings>

这是一个非常简单的示例,但您可以使用更复杂的对象来存储配置信息以及上下文中可用的其他属性,例如item.Attributescontext为了获得正确的配置值。

于 2013-02-04T15:44:14.403 回答