How to configure Interface having multiple concrete implementation using Castle Windsor (using code). Below is the sample code.
public interface ICostCalculator
{
double CalculateTotal(Order order);
}
public class DefaultCostCalculator : ICostCalculator
{
public double CalculateTotal(Order order)
{
return
order.Items.Sum(x => x.Product.Rate * x.Quantity);
}
}
The ServiceTaxCalculator implementation:
public class ServiceTaxCalculator : ICostCalculator
{
private readonly ICostCalculator calculator;
private double serviveTaxRate = 10.2;
public ServiceTaxCalculator(ICostCalculator calculator)
{
this.calculator = calculator;
}
public double ServiceTaxRate
{
get { return this.serviceTaxRate; }
set { this.serviceTaxRate = value; }
}
public double CalculateTotal(Order order)
{
double innerTotal =
this.calculator.CalculateTotal(order);
innerTotal += innerTotal * servieTaxRate / 100;
return innerTotal;
}
}
I want the instance of a concrete class based on service tax applicability. If service tax is applicable, I need ServiceTaxCalculator else DefaultCostCalculator.
How to configure this scenario using Castle Windsor.
Here's one way to do it:
container.Register(Component
.For<ICostCalculator>()
.UsingFactoryMethod(k =>
isServiceTaxApplicable ?
(ICostCalculator)k.Resolve<ServiceTaxCalculator>() :
k.Resolve<DefaultCostCalculator>()));
container.Register(Component.For<DefaultCostCalculator, ICostCalculator>());
container.Register(Component.For<ServiceTaxCalculator>());
Notice that the isServiceTaxApplicable variable in this example is an outer variable (not shown), but you can easily replace it with some other boolean check.
Also notice that the DefaultCostCalculator forwards the registration to the ICostCalculcator interface. However, since this is not the first registration of that interface, it's not the default registration.
It's important to register the DefaultCostCalculator after the factory method because this enables the Decorator pattern in those cases where the ServiceTaxCalculator is chosen.
Since we don't really know how you need to determine whether the service tax is applicable, I like to add another solution to Mark's nice answer. Here I use the decorator pattern:
// Decorator
public class ServiceTaxApplicableCostCalculator
: ICostCalculator
{
private readonly ICostCalculator with;
private readonly ICostCalculator without
ServiceTaxApplicableCostCalculator(
ICostCalculator with, ICostCalculator without)
{
this.with = with;
this.without = without;
}
public double CalculateTotal(Order order)
{
bool withTax = this.IsWithTax(order);
var calculator = withTax ? this.with : this.without;
return calculator.CalculateTotal(order);
}
private bool IsWithTax(Order order)
{
// determine if the order is with or without tax.
// Perhaps by using a config setting or by querying
// the database.
}
}
Now you can register this decorator:
container.Register(Component.For<ServiceTaxCalculator>());
container.Register(
Component.For<DefaultCostCalculator, ICostCalculator>());
container.Register(Component.For<ICostCalculator>()
.UsingFactoryMethod(k =>
new ServiceTaxApplicableCostCalculator(
k.Resolve<ServiceTaxCalculator>(),
k.Resolve<DefaultCostCalculator>())
)
);
Adding an answer to demonstrate #Kryzsztof's preference for service overrides. Instead of a factory method:
container.Register(Component.For<ICostCalculator>()
.UsingFactoryMethod(k =>
new ServiceTaxApplicableCostCalculator(
k.Resolve<ServiceTaxCalculator>(),
k.Resolve<DefaultCostCalculator>())
)
);
You would instead specify the dependencies via DependsOn:
container.Register(Component.For<ICostCalculator>()
.ImplementedBy<ServiceTaxApplicableCostCalculator>()
.DependsOn(Dependency.OnComponent("with", typeof(ServiceTaxCalculator)))
.DependsOn(Dependency.OnComponent("without", typeof(DefaultCostCalculator))));
The only benefit that is obvious to me is that if a different service is added to ServiceTaxApplicableCostCalculator's constructor, the service override case would continue to work without any changes (resolving the new service automatically), whereas the factory method would require another call to Resolve. Beyond that, it is certainly more idiomatic than using a factory method to explicitly create an object.
More information is available in the documentation.
Related
I've been struggling with a small DI problem, that I think should be very easy to solve, but for some reason I can't find the solution.
I have a service that should one one DI object in the same way for two different things.
public class EquationManager : IEquationManager
{
private readonly IEquationEvaluator _equationEvaluator;
private readonly IEquationEvaluator _inversEquationEvaluator;
public EquationManager(IEquationEvaluator equationEvaluator)
{
_equationEvaluator = equationEvaluator;
_inversEquationEvaluator = equationEvaluator;
}
}
So what I would need is 2 instances of the same DI. That's all. If I write the code as it is, they are shallow copies, what ever I set to _inversEquationEvaluator is also updated in _equationEvaluator ( which is normal).
How do I have 2 separate instances of the same DI? Is this possible in a simple way. I would like to avoid registering IEquationEvaluator in 2 different ways in the container.
My second question: is my architecture wrong? What I want to achieve here is having an math equation that takes an input parameter (int) and output a double value. I need now a way to revert this process using an other equation. So I input a double value and in theory I should obtain an int value. IEquationEvaluator is a class that deals with the math operation.
You can use this pattern:
public enum EquationEvaluatorType
{
EquationEvaluator,
InversEquationEvaluator
}
public interface IEquationEvaluator
{
public EquationEvaluatorType Type { get; }
//your methods and properties
}
public class EquationEvaluator : IEquationEvaluator
{
public EquationEvaluatorType Type => EquationEvaluatorType.EquationEvaluator;
}
public class InversEquationEvaluator : IEquationEvaluator
{
public EquationEvaluatorType Type => EquationEvaluatorType.InversEquationEvaluator;
}
public class EquationManager : IEquationManager
{
private readonly IEquationEvaluator _equationEvaluator;
private readonly IEquationEvaluator _inversEquationEvaluator;
public EquationManager(IEnumerable<IEquationEvaluator> items)
{
_equationEvaluator = items.First(x=>x.Type==EquationEvaluatorType.EquationEvaluator);
_inversEquationEvaluator = items.First(x => x.Type == EquationEvaluatorType.InversEquationEvaluator);
}
}
And in your startup:
services.AddScoped<IEquationEvaluator, EquationEvaluator>();
services.AddScoped<IEquationEvaluator, InversEquationEvaluator>();
I am using the excellent Simple Injector Ioc framework and would like to "plug in" multiple email output services ie Mandrill, MailChimp etc
My question really is am I doing this correctly as it results in a Cast at my send method.
So I have a simple IEmailOutputService
public interface IEmailOutputService
{
string Identifier { get; }
bool Send(object message, object contents);
}
And a MandrillOutputService (shortened)
public class MandrillOutputService : IEmailOutputService
{
public MandrillOutputService()
{
//DI stuff here
}
public string Identifier => "Mandrill";
public bool Send(EmailMessage message, IEnumerable<TemplateContent> templateContents)
{
if (message == null)
return false;
//send code here
return true;
}
bool IEmailOutputService.Send(object message, object contents)
{
//TODO this doesnt look right!!
var m = message as EmailMessage;
var c = contents as IEnumerable<TemplateContent>;
//forwards method onto bespoke Mandrill Send method above
return Send(m, c);
}
}
I have an EmailContext that gets the Email Output Provider for the logged in User eg "Mandrill" heres the IEmailContext
public interface IEmailContext
{
string GetProvider();
}
EmailOutputComposite is used to select correct Email Output Service
public class EmailOutputComposite : IEmailOutputService
{
private readonly IEmailContext _emailContext;
private readonly IEnumerable<IEmailOutputService> _emailOutputServices;
public string Identifier => "EmailOutputComposite";
public EmailOutputComposite(
IEmailContext emailContext, IEnumerable<IEmailOutputService> emailOutputServices)
{
this._emailContext = emailContext;
this._emailOutputServices = emailOutputServices;
}
bool IEmailOutputService.Send(object message, object contents) =>
this._emailOutputServices
.FirstOrDefault(x => x.Identifier.ToLower() == this._emailContext.GetProvider())
.Send(message, contents);
}
and finally registrations in Simple Injector
container.RegisterCollection(typeof(IEmailOutputService), new[]
{
typeof(MandrillOutputService)
//other emailOutputServices to go here
});
container.Register(typeof(IEmailOutputService), typeof(EmailOutputComposite),
Lifestyle.Singleton);
So my question is am I doing this correctly or is there a better way. I have to get the Users Email Provider (Mandrill) from Database so cant think of another way to do this but was concerned with the Cast I have to do in MandrillOutputService.Send method.
Wouldn't it be simpler to use the Strategy and Factory patterns, forgive me I'm going to change the implementation a bit:
For container registrations:
container.Register<EmailProviderFactory>(Lifestyle.Scoped);
container.Register<MandrillOutputService>(Lifestyle.Scoped);
container.Register<OtherOutputService>(Lifestyle.Scoped);
Then use a factory to resolve my email providers:
public class EmailProviderFactory
{
private readonly Container container;
public EmailProviderFactory(Container container)
{
this.container = container;
}
public IEmailOutputService Create(string provider)
{
switch (provider)
{
case "Mandrill": // should be in a constants class
return container.GetInstance<MandrillOutputService>();
case "Other": // should be in a constants class
return container.GetInstance<OtherOutputService>();
default: throw new ArgumentOutOfRangeException("provider");
}
}
}
I've changed the IEmailOutputService to have one method with explicit types:
public interface IEmailOutputService
{
bool Send(EmailMessage message, IEnumerable<TemplateContent> contents);
}
The email providers :
public class MandrillOutputService : IEmailOutputService
{
public bool Send(EmailMessage message, IEnumerable<TemplateContent> templateContents)
{
// ...
}
}
public class OtherOutputService : IEmailOutputService
{
public bool Send(EmailMessage message, IEnumerable<TemplateContent> templateContents)
{
// ...
}
}
Usage:
foreach(var userEmailProvider in UserEmailProviders) {
// I'm assuming the factory is injected
var emailService = _emailProviderFactory.Create(userEmailProvider.Name);
emailService.Send(new EmailMessage(), new List<TemplateContent>());
}
I do not think you need IEmailContext or a EmailOutputComposite. By using the EmailProviderFactory you will only create a specific provider when you need it.
I see two problems in your design:
You are violating the Liskov Substitution Principle in your MandrillOutputService by accepting only a subset of the accepted types of the IEmailOutputService abstraction; this might cause the appliation to break at runtime when the user supplies values that are invalid for that specific implementation.
The Identifier property on the IEmailOutputService violates the Interface Segration Principle, because it is a method that consumers don't use. The only class that is actually interested in this property is the EmailOutputComposite. Removing the Identifier from the abstraction has the advantage that it can simplify unit testing, since there is less code that a consumer can call. It also simplifies the interface, which is always a good thing.
I'm unsure how to fix the LSP principle, because its unclear to me how other implementations look like.
With respect to the ISP violation, you can do the following to fix it:
Mark the implementations instead with an attribute that defines their Identifier. This allows you to remove the property from the interface, but the downside is that the Composite can only filter those services in case the actual types are injected (and not decorated, because that disallows you from retrieving those attributes).
You let the Composite depend on the actual concrete implementations and implement a switch-case statement inside the Composite. This again allows you to remove the property from the interface, but downside is that you will have to update the composite every time a new implementation is added (which might not be that bad if you consider the Composite part of your Composition Root).
You define a dictionary of IEmailOutputServices during the registration process, where the Identifier is the dictionary's key. This removes the need to have the Identifier as part of the abstraction, but also removes the identifier from the implementation (which might actually be something good).
Here's an example of this last example:
container.RegisterSingleton<IEmailOutputService, EmailOutputComposite>();
container.RegisterSingleton(new Dictionary<string, Func<IEmailOutputService>>()
{
"Mandrill", CreateEmailServiceProducer<MandrillOutputService>(container),
"other", CreateEmailServiceProducer<Other>(container),
// ..
});
privte static Func<IEmailOutputService> CreateEmailServiceProducer<T>(Container c)
where T : IEmailOutputService =>
Lifestyle.Transient.CreateProducer<IEmailOutputService, T>(c).GetInstance;
Where the Composite is implemented as follows:
public class EmailOutputComposite : IEmailOutputService
{
private readonly IEmailContext _emailContext;
private readonly Dictionary<string, Func<IEmailOutputService>> _emailOutputServices;
public EmailOutputComposite(
IEmailContext emailContext,
Dictionary<string, Func<IEmailOutputService>> emailOutputServices)
{
_emailContext = emailContext;
_emailOutputServices = emailOutputServices;
}
public bool Send(object m, object c) => Service.Send(m, c);
IEmailOutputService Service => _emailOutputServices[_emailContext.GetProvider()]();
}
Whether or not this is actually an improvement is up to you.
I know this question might look like it's a duplicate but please let me explain.
So I created several components that use a pluggable architecture, basically I can freely add new implementations and they will be injected and processed automatically for me. This is really handy in several scenarios.
I'm going to talk about the simplest one, validating components.
One of the reasons to use a design like this is that I like to expose my roles explicitly as explained by Udi Dahan
Basically I have code like this:
public interface IValidatorRuner
{
void Run<TTarget>(TTarget target);
}
public class ValidatorRunenr : IValidatorRuner
{
private readonly IServiceLocator _serviceLocator;
public ValidatorRunenr(IServiceLocator serviceLocator)
{
_serviceLocator = serviceLocator;
}
public void Run<TTarget>(TTarget target)
{
// this is the dynamic/pluggable phase
// is this an antipattern???
var foundValdiators = _serviceLocator.GetAllInstances<IValidator<TTarget>>();
foreach (var valdiator in foundValdiators)
{
valdiator.IsSatisfiedBy(target);
}
}
}
This code lets me expose my validation rules explicitly like this:
//this will allow me to create validators in this way
//and they will be automatically injected and resolved for me
//(easy, to read, easy to write, easy to test, pff I could even smoke this validator easily)
public class OneValdiationRuleExplicitlyExposedAndEasyToTest : IValidator<Person>
{
public bool IsSatisfiedBy(Person target)
{
return target.Age > 18;
}
}
public class Person
{
public int Age { get; set; }
}
public interface IValidator<TTarget>
{
bool IsSatisfiedBy(TTarget target);
}
And I will use this code like this:
//usage
public class SomeCommandHandler
{
private readonly IValidatorRuner _validatorRuner;
public SomeCommandHandler(IValidatorRuner validatorRuner)
{
_validatorRuner = validatorRuner;
}
public void SomeMethod()
{
_validatorRuner.Run(new Person{Age = 16});
}
}
Validation was just one example, I also use it to fire domain events and to run pipelines and filters in the same pluggable way
Is using the service locator in this way an anti-pattern?
I know I might be hiding some dependencies, but the thing is that the dependencies are dynamically injected and discovered when the application initializes (Composition root)
Your thoughts will be greatly appreciated
In my opinion, the primary issue with your code sample is that the service locator is itself injected into the implementation of ValidatorRunner. For me, this is an anti-pattern, but perhaps not the one you're asking about.
Any answer I might give boils down to the capabilities of your service locator implementation. But for sure it should not be passed into the constructor of your class. Instead, the service locator should itself pass these things in when you ask it for an implementation of "IValidatorRuner"
As an example, you can inject a factory that knows how to load the dynamic validator instances for a given type.
If anyone is interested, I found a way to remove the ServiceLocator in my objects and still dynamically load/discover dependencies at run time.
The way I solved it was by registering my components in my DI container in the following way (using the Mediator pattern):
Binding mediator (shortbus) with/to ninject
var kernel = new StandardKernel();
kernel.Bind(x => x.FromThisAssembly()
.SelectAllClasses()
.InheritedFromAny(
new[]
{
typeof(IValidatorRunner<>)
})
.BindDefaultInterfaces());
And my final implementation looks like:
public interface IValidatorRuner<in TTarget>
{
void Run(TTarget target);
}
public class ValidatorRunenr<TTarget> : IValidatorRuner<TTarget>
{
private readonly IEnumerable<IValidator<TTarget>> _validators;
public ValidatorRunenr(IEnumerable<IValidator<TTarget>> validators)
{
_validators = validators;
}
public void Run(TTarget target)
{
foreach (var valdiator in _validators)
{
valdiator.IsSatisfiedBy(target);
}
}
}
Usage
//usage
public class SomeCommandHandler
{
private readonly IValidatorRuner<OneValdiationRuleExplicitlyExposedAndEasyToTest> _validatorRuner;
public SomeCommandHandler(IValidatorRuner<OneValdiationRuleExplicitlyExposedAndEasyToTest> validatorRuner)
{
_validatorRuner = validatorRuner;
}
public void SomeMethod()
{
_validatorRuner.Run(new Person{Age = 16});
}
}
In few words, by registering an opened generic type, my container resolves any call to that type creating a concrete-closed-generic-type instance at runtime for me.
As you can see in the usage, I do not have to create a specific concrete-closed-generic type of IValidatorRunner<OneValdiationRuleExplicitlyExposedAndEasyToTest> because the container creates one for me.
And there you go, now I'm happy because I removed the service locator from my domain objects =)
I have a class with the following structure
class Measure
{
public MeasureType measureType { get; set; }
public readonly IMeasureService _service ;
public Measure(IMeasureService service)
{
_service = service;
}
public Calculate()
{
_service.Calculate(this);
}
}
So i have different implementation of MeasureService for different measureTypes. Is it possible to use StructureMap to inject the corresponding MeasureService based on the measureType.
MeasureType is just an enum type and will never get changed throughout the instance.
StructureMap cannot be instructed to do that for a simple reason:
at the time the instance is created, the measureType property cannot be set.
you cannot set the IMeasureService dependency at a later time, because it's readonly (and should probably be private as well)
Therefore, the solutions to this problem have more to do with the design of your classes than with StructureMap.
Here are the solutions I would typically choose in such a scenario:
1) Delegate the task of choosing the right IMeasureService implementation to a different component.
The component could, for example, be called MeasureServiceFactory and have the following implementation:
public class MeasureServiceFactory
{
private readonly Func<MeasureServiceType1> _type1Service;
private readonly Func<MeasureServiceType2> _type2Service;
public MeasureServiceFactory(
Func<MeasureServiceType1> type1Service,
Func<MeasureServiceType2> type2Service)
{
_type1Service = type1Service;
_type2Service = type2Service;
}
public IMeasureService GetServiceForType(MeasureType type)
{
switch (type)
{
case MeasureType.Type1:
return _type1Service();
case MeasureType.Type2:
return _type2Service();
default:
throw new ApplicationException("Unexpected measure type!");
}
}
}
Note that StructureMap will automatically inject the two Funcs with appropriate calls to the container's GetInstance() method in order to properly resolve the required service.
Now, the Measure class will no longer have a direct IMeasureService dependency, but will depend on the factory instead:
public class Measure
{
public MeasureType measureType { get; set; }
private readonly MeasureServiceFactory _measureServiceFactory;
public Measure(MeasureServiceFactory measureServiceFactory)
{
_measureServiceFactory = measureServiceFactory;
}
public void Calculate()
{
var service = _measureServiceFactory.GetServiceForType(measureType);
service.Calculate(this);
}
}
Note that no StructureMap configuration is required. The container will be able to resolve everything correctly.
2) In order to keep the Measure class untouched, you could make the MeasureServiceFactory implement the IMeasureService interface:
public class MeasureServiceFactory : IMeasureService
{
private readonly Func<MeasureServiceType1> _type1Service;
private readonly Func<MeasureServiceType2> _type2Service;
public MeasureServiceFactory(
Func<MeasureServiceType1> type1Service,
Func<MeasureServiceType2> type2Service)
{
_type1Service = type1Service;
_type2Service = type2Service;
}
public void Calculate(Measure measure)
{
var service = GetServiceForType(measure.measureType);
service.Calculate(measure);
}
private IMeasureService GetServiceForType(MeasureType type)
{
switch (type)
{
case MeasureType.Type1:
return _type1Service();
case MeasureType.Type2:
return _type2Service();
default:
throw new ApplicationException("Unexpected measure type!");
}
}
}
Now, with your original Measure class, only this SM configuration is required to ake everything work:
x.For<IMeasureService>().Use<MeasureServiceFactory>();
3) If the logic inside the IMeasureService implementors is not very complicated, consider putting it in a single class and perform different things depending on the measureType of the Measure object (which you already have access to).
I know, this seems like a step back, but there are some cases in which I prefer to do just that: when the business logic is not overly complex and pretty unlikely to change.
This question is a result of a post by Jeffery Palermo on how to get around branched code and dependency injection http://jeffreypalermo.com/blog/constructor-over-injection-anti-pattern/
In his post, Jeffery has a class (public class OrderProcessor : IOrderProcessor) that takes 2 interfaces on the constructor. One is a validator IOrderValidator and an IOrderShipper interface. His method code branches after only using methods on the IOrderValidator interface and never uses anything on the IOrderShipper interface.
He suggests creating a factory that will call a static method to get the delegate of the interface. He is creating a new object in his refactored code which seems unnecessary.
I guess the crux of the issue is we are using IoC to build all our objects regardless if they're being used or not. If you instantiate an object with 2 interfaces and have code that could branch to not use one of them, how do you handle it?
In this example, we assume _validator.Validate(order) always returns false and the IOrderShipper.Ship() method is never called.
Original Code:
public class OrderProcessor : IOrderProcessor
{
private readonly IOrderValidator _validator;
private readonly IOrderShipper _shipper;
public OrderProcessor(IOrderValidator validator, IOrderShipper shipper)
{
_validator = validator;
_shipper = shipper;
}
public SuccessResult Process(Order order)
{
bool isValid = _validator.Validate(order);
if (isValid)
{
_shipper.Ship(order);
}
return CreateStatus(isValid);
}
private SuccessResult CreateStatus(bool isValid)
{
return isValid ? SuccessResult.Success : SuccessResult.Failed;
}
}
public class OrderShipper : IOrderShipper
{
public OrderShipper()
{
Thread.Sleep(TimeSpan.FromMilliseconds(777));
}
public void Ship(Order order)
{
//ship the order
}
}
Refactored Code
public class OrderProcessor : IOrderProcessor
{
private readonly IOrderValidator _validator;
public OrderProcessor(IOrderValidator validator)
{
_validator = validator;
}
public SuccessResult Process(Order order)
{
bool isValid = _validator.Validate(order);
if (isValid)
{
IOrderShipper shipper = new OrderShipperFactory().GetDefault();
shipper.Ship(order);
}
return CreateStatus(isValid);
}
private SuccessResult CreateStatus(bool isValid)
{
return isValid ? SuccessResult.Success : SuccessResult.Failed;
}
}
public class OrderShipperFactory
{
public static Func<IOrderShipper> CreationClosure;
public IOrderShipper GetDefault()
{
return CreationClosure(); //executes closure
}
}
And here is the method that configures this factory at start-up time (global.asax for ASP.NET):
private static void ConfigureFactories()
{
OrderShipperFactory.CreationClosure =
() => ObjectFactory.GetInstance<IOrderShipper>();
}
I just posted a rebuttal of Jeffrey Palermos post.
In short, we should not let concrete implementation details influence our design. That would be violating the Liskov Substitution Principle on the architectural scale.
A more elegant solution lets us keep the design by introducing a Lazy-loading OrderShipper.
I'm running late for a meeting, but a few quick points...
Sticking to the code branching of using only one dependency, there are two branches to propose:
Applying DDD practices, you would not have an OrderProcessor with a dependency on IOrderValidator. Instead, you'd make the Order() entity be responsible for its own validation. Or, stick to your IOrderValidator, but have its dependency within the OrderShipper() that is implemented - since it will return any error codes.
Ensure the dependencies being injected are constructed using a Singleton approach (and configured as Singleton in the IoC container being used). This resolves any memory concerns.
Like someone else that mentioned here, the point is to break the dependency on concrete classes and loosely couple the dependencies using Dependency Injection with some IoC container in use.
This makes future refactoring and swapping out legacy code far easier on a grand scale by limiting the technical debt incurred in the future. Once you have a project near 500,000 lines of code, with 3000 unit tests, you'll know first hand why IoC is so important.