34

ASP.Net MVC Webサイト用のカスタムメンバーシッププロバイダを作成中です。プロバイダは、より大きなライブラリの一部として別のクラスとして作成されています。バックエンドデータストアは、XmlファイルまたはSQLデータベースと同様に柔軟性が必要です。私の最初の考えは、データストア用のインターフェイスを作成し、これを依存関係注入を使用してプロバイダに注入することでした。依存関係注入とASP.Netメンバーシッププロバイダ

最終的には、開発者はデータストアインターフェイスを継承し、データを更新するために必要なメソッドを提供し、カスタムメンバーシッププロバイダによって使用される必要があります。

私のスキルが不足しているため、ウェブサイトに追加するときにクラスをメンバーシッププロバイダに注入する方法がわかりません。データストアをプロバイダにリンクするには何をする必要がありますか?ウェブサイトでこれを有効にする最も単純な方法は何ですか?

+0

依存性注入フレームワークに精通していますか? – Restuta

+0

@ Restuta - いいえ、私はフレームワークを探していません。この特定の要件には、単純なインタフェースで十分です。開発者は、インターフェイスを継承するだけで、独自のバックエンドストアを作成できるはずです。 – BinaryMisfit

+1

私はフレームワークがあなたに多くの時間を節約できると思います。これは、カスタムメンバーシッププロバイダに固有の実現を注入するために使用されます。このタスクは、プロバイダの初期化を制御できないため、最も複雑です。 – Restuta

答えて

31

Web.configファイルの<メンバシップ>要素を使用してカスタムメンバシッププロバイダを構成する場合は、依存性注入に関する問題を確認できます。

プロバイダーはフレームワークによって構築され、管理されており、IDataStoreインターフェイスの追加の依存関係注入を提供するために、その構成を傍受する機会はありません。

私の前提が正しい場合は、カスタムプロバイダーのInitialize()メソッドをオーバーライドし、そこで依存関係注入を実行します。プロバイダの構成で、IDataStoreを実装するタイプを指すカスタムの名前/値設定を持つことができます。これは辞書の一部としてInitialize()メソッドに渡されます。

その後、あなたはデータストア型のインスタンスを起動し、適切なプロパティにそれを設定します。それはあなたのプロバイダのインスタンスを作成した後にそれがあるので

public class MyMembershipProvider : MembershipProvider 
{ 
    public IDataStore DataStore 
    { 
     get; 
     set; 
    } 

    public override Initialize(string name, NameValueCollection config) 
    { 
     var dataStoreType = config["dataStoreProvider"]; 
     if (!String.IsNullOrEmpty(dataStoreType)) 
     { 
      var type = Type.GetType(dataStoreType); 
      DataStore = (IDataStore) Activator.CreateInstance(type); 
     } 
    } 
} 

Initialize()は、フレームワークによって呼び出されますこのような追加セットアップ作業を行うのに最適な場所です。

テストシナリオでは、テストで直接構築するため、プロバイダインスタンス自体にデータストアプロパティを設定するだけです。

+1

パーフェクト。私が探していたコード。ありがとうございました! – BinaryMisfit

+0

ここにある同様の方法で修正されています:http://bugsquash.blogspot.com.au/2010/11/windsor-managed-membershipproviders.html基本的には、あなたが作成したインスタンスをラップするためのデコレータデザインパターンを実装していますDIコンテナ。 –

+0

これはもはや.Net 4.6.2 – IronSean

2

私が見た依存性注入を行う最も簡単な方法は、従属クラスのコンストラクタにパラメータとしてインターフェイスを与え、それは私的なフィールドに。必要に応じて、デフォルトのコンストラクタを追加することもできます。このコンストラクタは、デフォルト値を持つ最初のコンストラクタにチェーンします。

public class DependentClass 
{ 
    private IDataStore _store; 

    // Use this constructor when you want strict control of the implementation 
    public DependentClass(IDataStore store) 
    { 
     this._store = store; 
    } 

    // Use this constructor when you don't want to create an IDataStore instance 
    // manually every time you create a DependentClass instance 
    public DependentClass() : this(new DefaultDataStore()) { } 
} 

コンセプトは、「コンストラクタの連鎖」と呼ばれ、それを行う方法については、ウェブ上の記事がたくさんあります:

簡体字、それはこのようになります。私はthis tutorial DIパターンの非常に説明を見つける。

+0

ありがとうございます。私はDIをかなり頻繁に使用するので、私はこの部分でかなり快適です。私の問題は、web.configで設定されるメンバーシッププロバイダに固有です。サムのソリューションはこの問題を解決します。 – BinaryMisfit

+0

@Sleeper:彼はASP.NET MVCを使用していると言います。つまり、コンテナを介してクラスを解決することは可能です。私は彼がすべきことを提案する。ところで、あなたは叫ぶ必要はありません。 –

20

これは良くありませんか?私はMVC3とそれを使っています。カスタムメンバーシッププロバイダクラスにプロパティを追加するだけで十分です。 「using System.Web.Mvc;」を追加することを忘れないでください。上に。

public IRepository Repository 
{ 
    get 
    { 
     return DependencyResolver.Current.GetService<IRepository>(); 
    } 
} 
+0

で動作するようです。私はこれをしばらく見ていませんでした。その時、質問はまだMVC 1.0だったと尋ねられました。 – BinaryMisfit

+1

それは私のために働きます。欠点は、それが "サービスロケータ"のパターンのバリエーションであることですが、アーキテクチャ上の妥協をしなければならないことがあります。 (http://stackoverflow.com/questions/22795459/is-servicelocator-anti-patternを参照してください)私は彼らがASP.NET vNextでこれを修正するはずですが、うまくいけばわかりません。 –

関連する問題