5

アプリケーション構成を簡素化するライブラリに取り組んでいます。基本的に、ライブラリのコンシューマーは、構成クラスを属性で装飾するか、コードで宣言的に設定を初期化します。構成プロパティ (アクセサ) を読み書きするソースを 1 つ以上指定するか、クラスからデフォルトを継承することができます。たとえば、次のようになります。

[ConfigurationNamespace(DefaultAccessors = new Type[] { typeof(AppSettingsAccessor) })]
public class ClientConfiguration : Configuration<IClientConfiguration>
{
    [ConfigurationItem(Accessors = new Type[] { 
        typeof((RegistryAccessor)) 
     })]
    public bool BypassCertificateVerification { get; set; }
}

と同等です

var config = new Configuration<IClientConfiguration>();
config.SetDefaultAccessors(new[] { typeof(AppSettingsAccessor) });
config.SetPropertyAccessors(
    property: x => x.BypassCertificateVerification,
    accessors: new[] { typeof(RegistryAccessor) }
);

アクセサーは、さまざまなソース (AppSettings、レジストリ、.ini など) からの読み取りと書き込みを処理します。消費者がニーズに合わせて機能を拡張できるようにしたいと考えています。私はそれをIoCコンテナにとらわれないようにしたいと思います。Type[] 制約が与えられているのは、コンパイル時と実行時の問題のために属性に型を指定できないためです。

これらをインスタンス化するためのデフォルトのメカニズム (たとえば、Activator.CreateInstance に基づくもの) を持つ方法はありますが、サービス ロケーター/依存関係リゾルバー パターンを使用せずに、消費するコードが実行時にこれらのアクセサーをインスタンス化できるようにする方法はありますか? サービスロケーター/依存関係リゾルバーパターンがなぜ悪のアンチパターンなのかについてよく読んでいますが、その仕事のためのより良いツールを見つけることができません。依存関係リゾルバーを使用している MVC フレームワークと SignalR ライブラリが表示されます。彼らは 100% 悪を行っているのでしょうか、それとも特殊なケースでしょうか? 私が知る限り、抽象的なファクトリ パターンは Type パラメータを好まないため、うまくいきません。

この特定のケースでは、属性ベースの構成は宣言型アプローチよりも有用であるため、構成属性を放棄したくありません (これにより、Type を IConfigurationAccessor に変更し、ファクトリ アプローチに切り替えることができます)。

4

1 に答える 1

5

DSL の作業から、API を他の表現モードから基礎となるセマンティック モデルに分離することが重要であることがわかっています。この場合、Configuration<T>API はセマンティック モデルのように見えます。属性ベースの DSL の後にセマンティック モデルをモデル化する理由はありません。このようなものは、私にとってはるかに理にかなっています:

var config = new Configuration<IClientConfiguration>();
config.DefaultAccessors.Add(new AppSettingsAccessor());
config.PropertyAccessorsFor(x => x.BypassCertificateVerification)
    .Add(new RegistryAccessor());

また、属性ベースのモデルを純粋に宣言型に変更します。

[AppSettingsConfiguration]
public class ClientConfiguration : Configuration<IClientConfiguration>
{
    [RegistryConfiguration]
    public bool BypassCertificateVerification { get; set; }
}

あとは、適応モデルからセマンティック モデルに変換する方法を見つけるだけです。

これは基本的に、他のシリアライゼーションリーダーと同じです。データを読み取り、その読み取り方法に関する型注釈からヒントを得ます。これは基本的に、データ構造の再帰的なウォークであり、ノードごとにアクセサーを作成する必要があります。

すべてのアクセサーが のようなインターフェースを実装すると仮定すると、これはAbstract FactoryIAccessorで拡張可能になります。

public interface IAccessorFactory
{
    IAccessor CreateAccessor(ConfigurationAttribute configurationAttribute);
}

実際、これはPLoPD4で説明されているProduct Traderと呼ばれるあまり知られていないデザイン パターンですが、ほとんどの人はこのパターンを知らないので、 Abstract Factoryと呼びます。無制限の型を返します - IAccessor インスタンスのみを返します。

于 2013-02-22T16:02:37.927 に答える