1

レガシーC#エンタープライズアプリに取り組んでいます。そのクライアントはいくつかのWebサービスを使用しており、そのURLは、他の多くの設定の中でも、ローカルのapp.configファイルから読み取られます。これらの設定をグローバルDBに移行して、管理を簡素化する必要があります。ただし、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.settingsますConsoleApplication1_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.Attributesまたはなどのコンテキストで使用可能な他のプロパティと組み合わせて構成情報を格納する場合があります。context

于 2013-02-04T15:44:14.403 に答える