8

コンテナに複数の実装がある場合、どのようにして城のウィンザーが実行時にインターフェイスの適切な実装を選択することができるでしょうか。

たとえば、IExamCalc と呼ばれる単純なインターフェイスを使用して、その試験で誰かがどのように成績を上げたかを計算するとします。

いいえ、たとえば、次のようないくつかの実装があります。

public interface IExamCalc
{
    int CalculateMark(ExamAnswers examAnswers)
}

public class WritenExam : IExamCalc
{
    public int CalculateMark(ExamAnswers examAnswers)
    {
         return 4;
    }
}

public class OralExam : IExamCalc
{
    public int CalculateMark(ExamAnswers examAnswers)
    {
         return 8;
    }
}

public class ExamMarkService
{
    private IExamCalc _examCalc;
    public ExamMarkService(IExamCalc examCalc)
    {
        _examCalc = examCalc;
    }

    public int[] CalculateExamMarks(ExamAnswers[] examAnswers)
    {
        IList<int> marks = new List<int>;
        foreach(ExamAnswers examanswer in examaAnswers)
        {
            marks.Add(_examCalc.CalculateMark);
        }
    }
}

ExamMarkService が Windor を介して reslove されているとします。正しい実装がコンストラクターに挿入されていることを確認するにはどうすればよいですか? これはマルチテナンシーの問題の例ですか?

すべてが理にかなっていることを願っています

コリン・G

4

3 に答える 3

12

David が言ったように、それはできませんが、IHandlerSelector を使用すると制御できます。テストをチェックして、それらの使用方法を理解してください: https://svn.castleproject.org/svn/castle/trunk/InversionOfControl/Castle.Windsor.Tests/HandlerSelectorsTestCase.cs

基本的には、次のようにします。

public class WritenExamHandler : IHandlerSelector
    {
        public bool HasOpinionAbout(string key, Type service)
        {
            // Decision logic here
            return somethingThatWouldBeTrueToSelectWritenExam && service == typeof(IExamCalc);
        }

        public IHandler SelectHandler(string key, Type service, IHandler[] handlers)
        {
            return handlers.Where(handler => handler.ComponentModel.Implementation == typeof (WritenExam)).First();
        }
    }

次に、それを次のように登録します。

container.Kernel.AddHandlerSelector(new WritenExamHandler());

これにより、マルチテナントの問題に簡単に対処できます:)

于 2008-11-25T23:32:11.077 に答える
3

マルチテナンシーは、1 つのインスタンスでソフトウェアを実行し、複数のテナント/顧客/クライアントにサービスを提供できるものとして定義されます。マルチテナンシー設定では、あなたのような問題に頻繁に遭遇する可能性があると思います。

container.Resolve("someKey")すべてのコンポーネントには一意の文字列であるキーがあるため、特定の実装を取得するために常にそうすることができます。

特定の実装を自動的に挿入したい場合は、次のようにコンポーネントを構成できます (私の記憶では、100% 正確ではない可能性があります)。

<component id="someService.customer1" service="ISomeService" type="Customer1SomeService" />

<component id="anotherId" service="IAnotherService" type="AnotherService">
    <parameters>
        <parameterName> <!-- as written in the ctor's signature -->
           ${someService.customer1}
        </parameterName>
    </parameters> 
</component>
于 2008-11-24T10:41:55.797 に答える
1

簡単に言えば、できません。この種の選択はアプリケーション コードに依存するため、単にcontainer.Resolve<IExamCalc>.

問題は、どのタイプを使用するかをどのように判断するかということです。

于 2008-11-24T10:03:28.010 に答える