0

私はしばしば、それ自体が機能するためにいくつかの依存関係をロードしなければならないいくつかのクラスを使用する必要があります。ただし、私のコンポーネントには複数の具体的な依存関係の実装を含めることができ、オブジェクトパラメータに基づいて別のコンポーネントではなく1つを選択します。

本当の問題は、アプリケーションの起動時にオブジェクトパラメータが常に不明であるため、現時点では依存関係を登録することも、解決することもできないことです。

代わりに、たとえば、それ自体が依存関係をロードする必要があるクラスを使用する必要がある場合concreteBuilder、適切な実装を返すために使用されるオブジェクトパラメーターを知っています。

interface ISample { }

class ParamForBuildSomeISampleImplementation
{
    // this instance cannot be create by my startUpApplication - Container - Resolver.
    // Instead, all time dependency is required (buttonClick, pageLoad and so on), this class can be instantiated.
}

class Sample1 : ISample 
{
    // some implementation
}

class Sample2 : ISample
{
    // some other implementation
}

class MyISampleFactory
{
    // Build ISample
    public ISample Build(ParamForBuilderISample obj)
    {
        // if obj.someProperty == ".." return new Sample1();
        // else if obj.someProperty == "--" return new Sample2();
        // else if ...
    }
}

class NeedsDependency
{
    ISample _someSample;
    public NeedsDependency(ISample someSample)
    {
        _someSample = someSample;
    }
}


// *** Controllor - ApplicationStartup - other ***
// Here I have not idea how to build ISample dependency

@@ EDIT 
// *** button click event handler ***
// Ok, here I know how to create ParamForBuilderISample, 
// hence I can call MyISampleFactory, then, I can Use NeedDependency class:
ParamForBuilderISample obj = new ...
obj.SomeProperty = ...
obj.otherSomeProperty = ...
ISample sample = MyISampleFactory.Build(obj);
NeedDependency nd = new NeedDependency(sample);
// perfect, now my buttonClick can execute all what it wants
nd.DoSomething();
nd.DoOtherStuff();

私のシナリオは依存性注入パターンに適していますか?本当の場合、私は自分のパターンをどのように構築するのか本当にわかりません。

4

1 に答える 1

0

この「ランタイム依存関係」を渡すためにコンストラクター注入を使用する代わりに、メソッド注入を使用する方がよい場合があります。これにより、ファクトリを持つ必要性が完全になくなる可能性さえあります。

private readonly ISample sample;

public MyController(ISample sample) {
    this.sample = sample;
}

public string button_click_event_handler(object s, EventArgs e) {
    ParamForBuilderISample obj = new ...
    obj.SomeProperty = ...
    obj.otherSomeProperty = ...

    this.sample.DoSomething(obj);
}

まだどこかを切り替える必要がありますが、ファクトリを持つ代わりに、次のプロキシを実装できますISample

public class SampleProxy : ISample
{
    private readonly Sample1 sample1;
    private readonly Sample2 sample2;

    public SampleProxy(Sample1 sample1, Sample2 sample2) {
        this.sample1 = sample1;
        this.sample2 = sample2;
    }

    public void DoSomething(ParamForBuilderISample param) {
        this.GetSampleFor(param).DoSomething(param);
    }

    private ISample GetSampleFor(ParamForBuilderISample param) {
        // if obj.someProperty == ".." return this.sample1;
        // else if obj.someProperty == "--" return this.sample2;
        // else if ...
    }
}

パラメータオブジェクトParamForBuilderISampleのように見えます。依存関係の挿入によって、メソッドの引数が不要になるわけではありません。データは引き続きメソッドを介して渡される必要があります。

于 2013-03-13T12:38:17.867 に答える