【问题标题】:Multiple Interface injection with castle windsor与城堡温莎的多接口注入
【发布时间】:2008-11-24 09:59:05
【问题描述】:

当容器中有多个实现时,如何让 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);
        }
    }
}

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

希望一切都有意义

科林·G

【问题讨论】:

    标签: dependency-injection inversion-of-control castle-windsor


    【解决方案1】:

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

    这将使您轻松处理多租户问题:)

    【讨论】:

      【解决方案2】:

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

      您的所有组件都有唯一字符串的键,因此您可以随时使用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>
      

      【讨论】:

        【解决方案3】:

        简短的回答是,你不能。这种选择取决于应用程序代码,所以如果你只是做了container.Resolve&lt;IExamCalc&gt;,那么温莎不知道你想要哪个。

        要问的问题是如何知道要使用哪种类型?

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-03
          相关资源
          最近更新 更多