8

当容器中有多个实现时,如何让 Castle Windsor 在运行时选择正确的接口植入。

例如,假设我有一个名为 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);
        }
    }
}

假设正在通过 Windor 重新使用 ExamMarkService 我如何确保在构造函数中注入了正确的实现,这是多租户问题的一个例子吗?

希望一切都有意义

科林·G

4

3 回答 3

12

正如大卫所说,你不能,但 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

多租户定义为能够在一个实例上运行您的软件,为多个租户/客户/客户提供服务。我猜你可能会在多租户设置中更频繁地遇到像你这样的问题。

您所有的组件都有唯一字符串的键,因此您可能总是这样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 回答