0

構成値へのアクセス(読み取り/書き込み)を担当するプラットフォーム/ファウンデーションコンポーネント(.NETアセンブリのセット)を作成しています。このコンポーネントは、プラットフォーム上に作成される他のコンポーネントによって使用されます。

このコンポーネントは、消費者にとって使いやすく、しかも高いテスト性と保守性を備えている必要があります。現在の設計では、いくつかのメソッド(GetKeyValueSettingなど)を含む静的クラス(ConfigurationManager)があります。このConfigurationManagerクラスは、ローカルの.NET .configファイルからだけでなく、SharePointリスト(一部のコンポーネントは共有SharePoint環境でホストされている)から、さらには別の共有構成値ストアからも構成値を取得できるという点で特別です。 。Managerは、優先順位を付けて複数の場所から読み取ることができる必要があります。

  • SharePointで実行している場合:1。SharePointSettingsProvider、2。SharedStoreSettingsProvider
  • SharePointで実行されていない場合:1。ConfigFileSettingsProvider 2. SharedStoreSettingsProvider

静的クラスは、テスト容易性、拡張性などに関して多くの問題を引き起こすことを知っているので、それを使用したくありません。私の次の選択肢はシングルトンですが、前述の-ilitiesに関しては、これはそれほど良い解決策ではありません。より良い解決策のためのアイデアはありますか?

私の現在のデザインは次のとおりです。

public static class ConfigurationManager
{
    // internal for testability
    internal IEnumerable<ISettingsProvider> SettingsProviders {get;set;}

    // internal for testability
    internal ISettingsProviderFactory ProvidersFactory {get;set;}

    public static string GetKeyValueSetting(string key)
    {        
    }
}

public interface ISettingsProvider
{
    string GetKeyValueSetting(string key);
}

public class ConfigFileSettingsProvider : ISettingsProvider
{
}

public class SharePointSettingsProvider : ISettingsProvider
{
}

public class SharedStoreSettingsProvider : ISettingsProvider
{
}

public interface ISettingsProviderFactory
{
    IEnumerable<ISettingsProvider> GetProviders();
}
4

1 に答える 1

1

なぜこれではないのですか?

public abstract class ConfigurationManager
{
    public abstract string GetKeyValueSetting(string key);

    public static ConfigurationManager GetInstance()
    {
         return GetInstance(GetDefaultSettingProvider(), GetDefaultProviderFactory());
    }

    public static ConfigurationManager GetInstance(ISettingsProvider provider, IProviderFactory factory)
    {
         return new InternallyVisibleConfigurationManagerImplementation(provider, factory);
    }
}

これには多くの利点があります。

  • ConfigurationManagerは抽象的であるため、コードを呼び出すと簡単にモックできます
  • デフォルトの実装を取得するのは簡単です
  • アセンブリを呼び出すと、さまざまなプロバイダーやファクトリで簡単に構成できます
  • 呼び出し元のアセンブリを具象型に結合することはできません
  • 特定の実装タイプを簡単に変更できます(つまり、キャッシュプロキシが必要なため、SharePointに頻繁に高額な呼び出しを行う必要がありません)
  • 簡単なテスト容易性をすべて維持します
  • クライアントコードを変更せずに、シングルトンまたはその他のライフサイクル管理のバリエーションにリファクタリングできます

発信者がこれを本当に嫌いで、SharePointサイトを呼び出すユニットテストを気にしない場合は、次のような便利なメソッドを追加できます。

public static string GetKeyValueSetting(string key)
{
    return GetInstance().GetKeyValueSetting(key);
}

編集

いくつかのストアを使用するには、次のようなクラスを作成します。

internal class OrderedCompositeSettingProvider : ISettingProvider
{
    private readonly ISettingProvider[] _providers;

    private OrderedCompositeSettingProvider(ISettingProvider[] providers)
    {
        _providers = providers;
    }

    internal static ISettingProvider GetInstance(params ISettingProvider[] providers)
    {
         return new OrderedCompositeSettingProvider(providers)
    }

    public string GetKeyValueSetting(string key)
    {
        foreach(var provider in _providers)
        {
             var setting = provider.GetKeyValueSetting(key);
             if(!string.IsNullOrEmpty(setting)) return setting;
        }
        return string.empty;
    }

}

次に、ConfigurationManagerファクトリメソッドで次のようにします。

public static ConfigurationManager GetInstance()
{
     return GetInstance(GetAppropriateProvider(), GetDefaultProviderFactory());
}

private static ISettingsProvider GetAppropriateProvider()
{
     if(ShouldUseSharepoint())
          return OrderedCompositeSettingProvider.GetInstance(new SharepointProvider(), new StoredSettingsProvider());

     return OrderedCompositeSettingProvider.GetInstance(new ConfigFileProvider(), new StoredSettingsProvider());
}
于 2013-01-26T16:42:37.200 に答える