Dependency injection have two instances of same dependency - c#

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

Related

How to pass the field to list of child objects in "has a" relationship

I have a class Step
public class TrainingStep
{
private List<Part> parts;
public Part currentPart;
public void AddPart(Part part)
{
parts.Add(part);
}
///a lot of public methods which are called from one layer above Step( a class containing Step list)
}
In this code the Part doesn't know anything about Step.
The currentPart is changing very often
and I want all of parts to know which is the current now
To achieve this I considered to add step as a parameter for Part class constructor, in order every part knows to which Step it belongs.
Something like this
public Part(Step step, ...)
{
this.step = step;
}
But the problem of such kind of solution is that I can access every public method in Step class from Part using the reference which I've passed via constructor.
But I want to access only currentPart field from Part.
How can I achieve this?
You might define a Func<Part> which returns your currentPart and pass this delegate to your parts.
public class TrainingStep
{
private List<Part> parts;
public Part currentPart;
private Func<Part> getCurrentPartFunc = () => currentPart;
public void AddPart(Part part)
{
part.GetCurrentpart = getCurrentPartFunc;
parts.Add(part);
}
}
class Part
{
public Func<Part> GetCurrentPart {get; set;}
}

Is Service Locator an anti pattern in a pluggable architecture?

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 =)

Creating Object on the basis of type base on a condition

I am facing a unique problem. We have a download functionality in our application in which we have a drop-down which contains type of file user need to download i.e. pdf,csv or excel
To implement this problem we have create one Interface IFileDownaload and three different class clsCSV,ClsPDF and clsExcel which are implemented by IFileDownaload
Now my problem is how to inititate a class on the basis of Dropdown value because i dont want to write down if-else statement
if(option=="pdf") type
because in future if we introduce a new file download type then it will impact us to re-write whole logic again
Any suggestion
You can define abbreviation for each class you have, so that you'll have something like this:
public interface IFileDownload
{
string Abbreviation { get; }
}
public class PDFDonwload : IFileDownload
{
public string Abbreviation { get; private set; }
}
Then you can make some class, i.e. factory, which have instances of all filedownloaders you have and which iterates through their Abbreviations till it finds proper class. It can be implemented like this:
public static class DownloadHander
{
private static List<IFileDownload> _handlers;
static DownloadHander()
{
_handlers = new List<IFileDownload>();
}
public static void Initialize()
{
_handlers.Add(new PDFDonwload());
}
public static Stream HandleDownload(string abbreviation)
{
foreach (var fileDownload in _handlers)
{
if (fileDownload.Abbreviation == abbreviation)
{
//and here you make a stream for client
}
}
throw new Exception("No Handler");
}
}
When I have a number of classes which implement a certain type and those classes are stateless services rather than entities, I use a Registry rather than a Factory.
Your Registry has instances of all the IFileDownload-implementing classes injected into it in an array:
public class FileDownloaderRegistry
{
private readonly IFileDownload[] _downloaders;
public FileDownloaderRegistry(IFileDownload[] downloaders)
{
_downloaders = downloaders;
}
}
You then have a property on IFileDownload which indicates the file type handled by the downloader:
public interface IFileDownload
{
string FileType { get; }
// etc.
}
And finally a method on your Registry which takes the file type and delegates the work to the appropriate downloader:
public string DownloadFile(string fileName, string fileType)
{
var handlingDownloader = _downloaders
.FirstOrDefault(d => d.FileType == fileType);
if (handlingDownloader == null)
{
// Probably throw an Exception
}
return handlingDownloader.Download(fileName);
}
DI containers will often implicitly understand arrays, so just registering the various IFileDownloads should end up with them in the array injected into the Registry's constructor. e.g. with StructureMap you use:
For<IFileDownload>().Use<ClsCSV>();
For<IFileDownload>().Use<ClsPDF>();
For<IFileDownload>().Use<ClsExcel>();
Adding a new IFileDownload is then a matter of writing the class and adding it to the set of IFileDownloads registered with your DI container. You can also have the container manage the lifetimes of each object so (if they're stateless) they're only instantiated once each, when they're first needed.

Injecting Corresponding implementation using StructureMap

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.

Polymorphism with Dependency Injection using Castle Windsor

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.

Categories