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 в настоящее время resloved через WINDOR как я могу убедиться, что правильная реализация впрыскивается в конструкторе и это пример проблемы с несколькими арендаторами?

Надежда, что все делает Sence

Colin G

ответ

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()); 

Это будет позволяют легко справляться с проблемами с несколькими факторами:

1

Короткий ответ, вы не можете. Такой выбор зависит от кода приложения, поэтому, если вы только что сделали container.Resolve<IExamCalc>, тогда Виндзор не мог знать, какой из них вам нужен.

Вопрос, как сделать вы знаете, какой тип использовать?

3

Multi-tenancy определяется как возможность запуска вашего программного обеспечения в одном экземпляре, обслуживающего несколько арендаторов/клиентов/клиентов. Наверное, вы можете чаще сталкиваться с такими проблемами, как ваша, в настройке с несколькими арендаторами.

Все ваши компоненты имеют ключи, которые являются уникальными строками, поэтому вы всегда можете найти 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>