How can you get castle Windsor to choose the right implantation of a interface at run time when you have multiple implementations in the container.
For example lets say i have a simple interface called IExamCalc that does calculations to work out how someone did in that exam.
No we have several implementation of this like bellow for example,
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);
}
}
}
Say the ExamMarkService is being resloved through Windor how can i make sure that the correct implementation is injected in the constructor and is this an example of a multi-tenancy problem?
Hope that all makes sence
Colin G
As David said, you can't, but IHandlerSelector will let you take control. Check out the tests to get an idea of how to use them: https://svn.castleproject.org/svn/castle/trunk/InversionOfControl/Castle.Windsor.Tests/HandlerSelectorsTestCase.cs
Basically, you would do something like:
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();
}
}
and then you register it with:
container.Kernel.AddHandlerSelector(new WritenExamHandler());
This will allow you to easily deal with multi-tenency issues :)
Multi-tenancy is defined as being able to run your software on one instance, serving multiple tenants/customers/clients. I guess you could run into problems like yours more often in a multi-tenancy setup.
All your components have keys which are unique strings, so you may always so a container.Resolve("someKey")
to get a specific implementation.
If you want to have a specific implementation automatically injected, you may configure your component like this (off my memory, may not be 100% precise):
<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>
The short answer is, you can't. This kind of choice is dependent on application code, so if you just did container.Resolve<IExamCalc>
, then Windsor couldn't know which one you wanted.
The question to ask is how do you know which type to use?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With