2

ここ数日、C#.NET (4.0RC) で新しいプロジェクトを開始することを考えています。プロジェクトの最終結果は、私が現在「ProviderFactory」と呼んでいるもの、いくつかのインターフェイス (または抽象クラス)、およびデフォルトの「ProviderType」または 2 つから構成されるクラス ライブラリになります。

まず第一に、.NET に既にあるものと衝突しないように、クラスの名前を変更する必要がある/決定する場合があります。第 2 に、ここで説明しているものは既に存在している可能性が高いため (私が知らないうちにネイティブに .NET 内にある可能性もあります)、その場合は、そのプロジェクトまたはチュートリアルへの単一のリンクをいただければ幸いです。

私が考えている機能は、単純なプロバイダーを提供できる単なるファクトリーではなく、あらゆる種類のプロバイダーを生成できるはずです。私はこのようなものを書くことができるようにしたい:

BlogProvider bp = ProviderFactory.GetProvider<BlogProvider>();

現在選択されている BlogProvider を返すか、存在しない場合は null を返す必要があります。また、たとえば、1 つのタイプの利用可能なすべてのプロバイダーのリストを提供できるようにしたい

string[] blogproviders = ProviderFactory.GetRegisteredProviders<BlogProvider>();

また、ブログ プロバイダ (「ODBCBlogProvider」、「XMLBlogProvider」など) を含む文字列の配列を返す必要があります。たとえば、次のように、現在のプロバイダーを設定できるようにする必要もあります。

ProviderFactory.SetCurrentProvider<BlogProvider>("ODBCBlogProvider");

これにより、現在の BlogProvider が ODBCBlogProvider になるため、次に ProviderFactory.GetProvider() を呼び出すと、ODBCBlogProvider のインスタンスが返されます (これにより、BlogProvider 基本クラスを拡張する必要があります)。

また、すべての ProviderType (または必要に応じて ProviderBase) には、その ProviderType に固有の ProviderTypeName (BlogProvider) と ProviderTypeDisplayName (「ブログ」または「ブログ プロバイダー」) が必要であり、そのプロバイダーを拡張するすべての Provider には、 ProviderName (ODBCBlogProvider) と ProviderDisplayName (「ODBC」または「ODBC ブログ」など)。ProviderName と ProviderTypeName は、簡単にするために、リフレクションによって取得されたクラス名が存在する可能性があります。

これはおそらく、次のような ProviderBase のインターフェイスが必要であることを意味します。

public interface ProviderBase
{
    string ProviderName { get; } // The display-name.
    string Description { get; } // A description of the provider type, like "This provides you with a blog."
}

また、BlogProvider については、これら 2 つのメンバーを実装し、実際の BlogProvider がオーバーライドするメソッドを作成する抽象クラスを作成する必要があります。

public abstract class BlogProvider : ProviderBase
{
    public string ProviderName
    {
        get { return "Blog"; }
    }

    public string Description
    {
        get { return "This provides you with a blog."; }
    }

    public abstract int GetPostCount();
}

次に、コードのどこかで次のようなものを実行する必要がありました

ProviderFactory.RegisterProviderType(typeof(BlogProvider));

または、さらに良いオプションは、次のような属性を使用できるようにすることです。

[Provider("Blog", "This provides you with a blog.")]
public interface BlogProvider
{
    int GetPostCount();
}

基本クラスにメンバーを設定する必要がないため、このアプローチで抽象クラスを使用する必要はないと思います。また、ProviderBase インターフェースの必要性もなくなりました。理想的な原因は、ProviderFactory が ProviderAttribute を含むすべてのクラス/インターフェイスを見つけることができ、ODBCBlogProvider が BlogProvider を実装するだけでよい場合ですが、これを行う方法がわかりません。 providers と providertypes はどちらも外部アセンブリに使用できます。

ProviderFactory のもう 1 つの要件は、ステートレス環境とそれが維持される環境の両方で機能する必要があることです。したがって、設定をいくつかの構成ファイル/ストリーム/データベースに保存できる必要があります (そのようなものは、'これは、初期化時にこれから変更およびロードするときに重要ですが、これはオプションである必要があります。したがって、Web 上でも機能します (自分のマシンでブログを作成しても意味がありません)。

もう 1 つの要件は、プロバイダーが他のプロバイダーの動作を必要とする可能性があることです。たとえば、AudiEngine は AudiCar でしか動作しませんが、AudiCar は BmwEngine で完全に動作します。

また(そして、どこに置くべきかまだわかりません。おそらくプロバイダークラス自体のオプションの属性です)すべてのプロバイダーには、シングルトンであるかどうかのオプションが必要です。

今のところ思いつくのはそれだけです。これがどのように実装されるべきか、またはすでに実装されている天気についての意見は大歓迎です。まだコードを書いていないので、何でも変更できます。これはすべて私が今考えていることです。

4

2 に答える 2

2

うーん、オーバーエンジニアリングされた (というより、過度に派手な名前の) IoC/DIコンテナーのように見えます。

IoC の考え方はほとんど同じですが、それら (コンテナー) は「コラボレーター」がインターフェイスを実装したり、基本クラスから派生したりする必要がないという点が異なります。

var builder = new ContainerBuilder();
builder.Register<Car>();
builder.Register<Engine>().As<IEngine>();

var container = builder.Build();

// somewhere in the code
var car = container.Resolve<Car>();

これは、C#/.NET 用の無数の DI コンテナーの 1 つであるautofacを使用した例です。

于 2010-03-09T13:16:04.770 に答える