2016-11-07 2 views
2

コンストラクタのプロパティでDIを使用する際に問題があります。私はIPDFBuilderに基づいてPDFBuilderを構築しています。動的コンストラクタインジェクションを使用するDI

public interface IPDFBuilder 
{ 
    string templatefilepath { get; } 
    string templatefilename { get; } 
    Dictionary<string, string> dict { get; }  
    void CreatePDF(); 
} 

public class PDFBuilder : IPDFBuilder 
{ 
    public string templatefilename { get; private set; } 
    public string templatefilepath { get; private set; } 
    public Dictionary<string, string> dict { get; private set; } 

    public PDFBuilder(string templatefilename, string templatefilepath, Dictionary<string, string> dict) 
    { 
     this.templatefilename = templatefilename; 
     this.templatefilepath = templatefilepath; 
     this.dict = dict; 
    } 

    public void CreatePDF() { 
     //Do something 
    } 
} 

このPDFBuilder缶例えば、複数のコントローラで使用される:

public class KeuringController : Controller 
{ 
    private IPDFBuilder _PDFBuilder; 
    public KeuringController(IPDFBuilder pdfBuilder) 
    { 
     _PDFBuilder = pdfBuilder; 
    } 
    //Action methods that use `PDFBuilder` below... 
} 

しかし、私は、起動クラスのPDFBuilderのプロパティを設定することができない(DI登録が行わbeeingてさ)異なるコントローラがPDFBuilderクラスのプロパティに対して異なる値を使用するからです。 1つの単純な解決策は、プロパティの設定をパブリックにすることで、アクションメソッドでは値を設定してからCreatePDF()を呼び出すことができます。しかし、これは正しいとは感じません。

public void CreatePDF(string templatefilename, string templatefilepath, Dictionary<string, string> dict) { 
     //Do something 
    } 

しかし、今の私のPDFBuilderは、これらすべてを必要とする10個の方法を持ってwhouldとしましょう:別の簡単な解決策は、クラスのプロパティを削除し、ちょうどこのようCreatePDFメソッドにメソッド・プロパティとしてPDFBuilderの3つのプロパティを渡すことであろう3プロパティ。それから、これは正しい解決策ではありませんか?

正しい解決策は何ですか?私はこの問題をさまざまなクラス/インターフェイスの実装で複数回遭遇しましたが、これらの状況での設計にいくつかの助けをしたいと思います。

+1

これらのパラメータ/プロパティの値はどこから得られますか?設定ファイル?またはユーザーからですか? –

答えて

4

コンポーネントのコンストラクタにランタイムデータを挿入しています(bad thing)。ソリューションはCreatePDFメソッドにコンストラクタのうち、それらの実行時の値を移動することです:

public interface IPDFBuilder 
{ 
    void CreatePDF(string templatefilepath, string templatefilename, 
     Dictionary<string, string> dict); 
} 
+0

これらがランタイムデータであるかどうかは明らかではありません。おそらく、これらは構成ファイルからの構成データです。 –

+0

@ YacoubMassad:質問には、「異なるコントローラーがプロパティーに対して異なる値を使用するため」という質問があります。これは、それがランタイムデータであると結論づけます。しかし、あなたは正しいです、それはまだ構成データであり、それは答えを変えるでしょう。 – Steven

+1

遅い回答に申し訳ありませんが、私はランタイムデータを明確に記しています!私はこれをスティーブンが私たちに与えた答えが優れた指針である理由としてマークします。 –

0

あなたがサブクラス化(またはプロトタイプ、あなたの要件に応じて)PDFBuildersの種類と応じたクラスにそれらを注入できます。

使用しているDIフレームワークはわかりませんが、フレームワークに特定のクラスにどのような依存性を注入するかを伝えるオプションがあります。

編集:注意:この解決策は、実行時に知られている値には適用されません。

0

あなたが欲しいものをやっての二つの方法があります:

1) Create factory for builder. 

2) Create configurator for builder. 

あなたが工場を作成するときに、あなたは基本的にオブジェクトが作成されるので、自由にあなたが別のビルダーのためのさまざまな実装にしたいすべてのものを設定する方法を指定します。

public inteface IPDFBuilderFactory 
{ 
    IPDFBuilder Create(); 
} 

すべての依存関係を渡す必要があります。これは欠点です。私は個人的にこの方法が嫌いです。

public interface IPDFConfiguration 
{ 
    string templatefilename {get;} 
    string templatefilepath {get;} 
    Dictionary<string, string> dict {get;} 
} 

とコンストラクタの引数として渡し:

もう一つの方法は、このような構成を作成することです

public PDFBuilder(IPDFConfiguration configuration) 
{ 
    ... 
} 

あなたはdeside場合、それはあなたのビルダーの初期化でよりflexebilityを与えますそれらをある時間変更する。

あなたの設定は、時間がたつにつれて非常に不器用になる可能性があり、リファクタリングをしないと他の人のブラックホールになることがありますので、注意してください。

あなたに最適なものを選択してください。

関連する問題