How to do this without using an IF condition - c#

I have an interface that defines one method. This interface has multiple classes that implement that interface differently.
eg:
interface IJob {
void DoSomething();
}
class SomeJob : IJob{
public void DoSomething() {
// Do something ...
}
}
class AnotherJob : IJob {
public void DoSomething() {
// Do something ...
}
}
...
My factory class will have a bunch of these IF statements
if (some condition)
{
IJob job = new SomeJob ();
else
{
IJob job = new AnotherJob ();
}
Is there a way to avoid modifying the factory class every time a new condition arises. Can this not be done just by adding a new class that implements IJob ?
Edit:
[I am trying to figure out what these guys at the Antiifcampaign are trying to do]
Thanks for your time...

You have to connect a condition and a decision in some way.
Dictionary<int, Action<IJob>> _methods = new ...
fill the dictionary:
_methods.Add(0, () => {return new SomeJob();});
_methods.Add(1, () => {return new AnotherJob();});
then use it:
public IJob FactoryMethod(int condition)
{
if(_methods.ContainsKey(condition))
{
return _methods[int]();
}
return DefaultJob; //or null
}
You need to fill the dictionary on the application startup. From config file, or with some other code.
So you don't need to change factory when you have a new condition.
Do you like this variant?

Somewhere the decision of what to create has to be made, and it's likely to always involve a conditional statement of some sort.
But you can reduce the need to modify the factory class by using reflection if you can arrange things to follow reasonable naming conventions and/or add reflective supports such as attributes.
See this article for some ideas of how to do this in .Net
You can also base the decision on a map of strings to classnames or even as in another good answer to methods, loaded on application startup, and create the classes at runtime by reflection. Something has to supply the map, but you might be able to move much of the decision to configuration.

It depends on the dynamics of your domain. If you need to evaluete the condition very often you can have some sort of factories for each implementation of IJob, for example SomeJobFactory, AnotherJobFactory, ...
Each will have method MeetsCondition that will evaluate to true if the condition is met and then return the new instance.
public class SomeJobFactory : Factory<IJob>
{
public bool MeetsCondition() { ... }
public IJob CreateInstance() { return new SomeJob(); }
}
And in your code
foreach(var jobFactory in allJobFactories)
{
if(jobFactory.MeetsCondition())
{
return jobFactory.CreateInstance();
}
}
You also use IoC to get all the job factories:
allJobFactories = IoC.ResolveAll<Factory<IJob>>();
When you add new job factory you don't have to modify a single line of code in this example.
If your code is more static you can use the DI and IoC where the object is created once on the startup.

I don't prefer you but you can always use generics:
public IJob GetJob<T>() where : IJob ,new()
{
IJob job = new T();
return job;
}

Related

Create mock of class without calling original class constructor

Say i have library with this code (that canot be changed)
namespace Library.Namespace;
public interface ISomething { }
internal class Something : ISomething {
public Something(...) {
...
}
}
public class Anything {
private Something _Something;
public Anything (ISomething something) {
_Something = (Something) something;
...
}
}
and i want to create mock of Anything class:
public MockAnything : Mock<Anything> {
public MockSomething Something { get; }
public MockAnything()
: this(new MockSomething()) {
}
public MockAnything(MockSomething something)
: base(something.Object) {
Something = something;
}
}
public MockSomething : Mock<ISomething> {
}
everythig good so far (aka compiller is happy), but at runtime im getting exception when calling:
var mock = new MockAnything();
var object = mock.Object; // <-- exception here
System.InvalidCastException
Unable to cast object of type 'Castle.Proxies.ISomethingProxy' to type 'Library.Namespace.Something'.
at Library.Namespace.Something..ctor(ISomething something)
at Castle.Proxies.AnythingProxy..ctor(IInterceptor[] , ISomething something)
any idea how to correctly mock class, that uses direct cast in constructor?
When using Moq, the best and easiest way is to create mocks based on interfaces. Unfortunately, you cannot change the library and add an interface there or get rid of the cast (which would be best anyway).
From a design perspective, I'd recommend to create a wrapper around the library code that you cannot change. In addition, you create an interface (let's call it IAnything) that contains the methods that you want to use. Instead of using Anything directly in your code, you'd inject IAnthing into your code. The following code outlines the necessary classes:
public IInterface IAnything
{
// Members of the original Anything class that you want to use in your code
}
public class AnythingWrapper : IAnything
{
private readonly Anything _anything;
public AnythingWrapper(Anything anything)
{
_anything = anything;
}
// IAnything implementation
}
While this might seem like a bit of extra work, it usually is done with some paste-and-copy. In addition, you create a layer of abstraction between your code and the library code. If the library changes in the future, you could be able to apply the changes in your wrapper class without changing the interface as such.
As soon as you have created the interface, you can easily create a mock, e.g.:
var mockAnything = new Mock<IAnything>();

Create instance by enum value + dependency injection

I have some handler classes in my application which are created in runtime according to passed enum value. It looks like this:
public interface IMyHandler
{
void Handle();
}
public class SimpleHandler : IMyHandler
{
public void Handle()
{
//logic here...
}
}
public class ComplexHandler : IMyHandler
{
public void Handle()
{
//logic here...
}
}
public enum HandlerTypes
{
Simple,
Complex
}
public class Hanlderfactory
{
public IMyHandler CreateHandler(HandlerTypes type)
{
switch(type)
{
case HandlerTypes.Simple:
return new SimpleHandler();
case HandlerTypes.Complex:
return new ComplexHandler();
default:
throw new NotSupportedException();
}
}
}
It's ok for me. But there is a problem here if I want to inject some components in my handlers like this:
public class SimpleHandler : IMyHandler
{
public SimpleHandler(IComponentOne c1, IComponentTwo c2, IComponentThree c3)
{
//...
}
public void Handle()
{
//logic here...
}
}
I use Unity IoC container and of course I want to use it here. But it looks ugly to call Resolve method here manually. Am I on wrong path? How to use both of this patterns together gracefully? Is it a single option here to call IoC container inside facotry?
UPDATE: I tried to use injection of delegate with InjectionFactory class. It works fine. But in this case if I need such factory logic in two applications I need to register this delegate and mapping between enums and classes in both applications startup:
var container = new UnityContainer();
container.RegisterType<IMyHandler, SimpleHandler>(HandlerTypes.Simple.ToString());
container.RegisterType<IMyHandler, ComplexHandler>(HandlerTypes.Complex.ToString());
container.RegisterType<Func<HandlerTypes, IMyHandler>>(new InjectionFactory(c => new Func<HandlerTypes, IMyHandler>(type => c.Resolve<IMyHandler>(type.ToString()))));
Using Enum with a factory is a code smell that indicates you need to do more refactoring.
An alternative is to use the strategy pattern as in this example. Note the use of Type instead of an Enum ensures you only have to change one piece of code when the design changes (you could alternatively use a string datatype).
Another alternative would be to inject a Func into the factory so your DI container can resolve instances.
Injecting the container into an abstract factory is a way of making a framework extension point. As long as the factory is part of your composition root, this is okay.

Injecting a dictionary of factories with Ninject

I know how I can inject one or a collection of dependency interface instances into a class via constructor injection. However, in my current situation I have a bit different task.
I have several classes, and each of them has an associated "Processor" class. These processors are implementing the same IProcessor interface, and a common Processor class will process a collection of objects, using the appropriate processors for each of them. Creating a processor for a type can be expensive, so I'm using factories and instantiate the processor only when it's needed.
The code would look something like this.
public interface IProcessor {
void Process(object item);
}
public class Processor {
private readonly Dictionary<Type, Func<IProcessor>> _processors;
public Processor(IDictionary<Type, Func<IProcessor>> processors) {
_processors = processors;
}
public void Process(IEnumerable items) {
foreach (var item in items) {
var processorFactory = _processors.GetValueOrDefault(item.GetType());
if (processorFactory == null) continue; // for simplicity
var processor = processorFactory();
processor.Process(item);
}
}
}
How could I register the binding for this in Ninject? Or is there any kind of alternative patterns which are more "DI friendly"?
I would like to configure these "processor bindings" at application entry point level.
An alternative would be to have a static dictionary of processor factories in the Processor class, and register the bindings manually at the entry point, but I would like to avoid using static dependencies. Or would it be still better in this particular case?
UPDATE
Another, kind of hybrid alternative which I arrived to is something like this. I would have a static Factories dictionary in the Processor class. There I could have basic, default implementations as a facade.
Then in my Ninject module I could write something like this.
public class MyModule : NinjectModule
{
public override void Load()
{
// ... my "standard" bindings
Processor.Factories[typeof(MyItem1)] = () => Kernel.Get<MyItem1Processor>();
Processor.Factories[typeof(MyItem2)] = () => Kernel.Get<MyItem2Processor>();
}
}
I know that I'm using the "evil" static stuff here, but still can utilize DI quite easily and in a well readable way, utilizing the Kernel property of the module.
Is it safe to use the Kernel property of the module inside the Load method? I mean can a module be loaded into more kernels for example?
Any thoughts are appreciated.
I'm answering my question with my final solution.
I believe, that in software development process if something "doesn't want to be put together", then it's an indication of some smell and most of the times I needed to get back a few levels to find it. It's something similar here too.
I realized that it's not a good design to use the factory pattern in this scenario because:
I think instantiating a processor object should never be so expensive, as each processor object should optimize their resources to use them only if Process is called.
Even if instantiation is expensive, with my original pattern, whenever a suitable object is in the processed list, a new instance is created. (This could be handled by the processor, but still doesn't look good at all.)
No way to add custom processors with respect to priority. Let's say ProcessorA processes ClassA, ClassB extends ClassA and ProcessorB processes ClassB. I have no way to prevent ProcessorA to process ClassB and allow other (non custom processed) ClassA descendandts to be still processed with ProcessorA at the same time. This is because of the Dictionary structure.
So I decided to simplify the implementation and pass an enumerable of IProcessors directly to the main processor, and have a CanProcess(object obj) in IProcessor. This way I can directly use any DI container to inject a list of all bound implementations.
If you want lazy initialization, how about a factory class rather than a Func?
Have a base factory class:
public abstract class ProcessorFactory
{
public abstract Type ItemType { get; }
public abstract IProcessor GetProcessor();
}
Create a concrete instance of the class for each item type and inject a collection of those into your constructor. Then build your dictionary from that:
public class Processor
{
private readonly Dictionary<Type, ProcessorFactory> _processors;
public Processor(IEnumerable<ProcessorFactory> processors)
{
_processors = processors.ToDictionary<ProcessorFactory, Type>(p => p.ItemType);
}
public void Process(IEnumerable items)
{
foreach (var item in items)
{
var processorFactory = _processors.GetValueOrDefault(item.GetType());
if (processorFactory == null) continue; // for simplicity
var processor = processorFactory.GetProcessor();
processor.Process(item);
}
}
}
Update 1
Here's sample code for the full factory implementation:
First I changed the factory to an interface:
public interface IProcessorFactory
{
Type ItemType { get; }
IProcessor GetProcessor();
}
Then I created an abstract generic base class for the factories:
public abstract class ProcessorFactoryBase<TItem> : IProcessorFactory
{
private Lazy<IProcessor> _factory;
public ProcessorFactoryBase(Func<IProcessor> factory)
{
_factory = new Lazy<IProcessor>(factory);
}
public Type ItemType
{
get { return typeof(TItem); }
}
public IProcessor GetProcessor()
{
return _factory.Value;
}
}
To create a factory, simply inherit from the base with the appropriate item type and implement the constructor:
public class ProcessorFactoryA : ProcessorFactoryBase<ItemA>
{
public ProcessorFactoryA(Func<IProcessor> factory) : base(factory) { }
}
Note that the factory class is tied to the item type; the processor type is injected via the bindings:
public class Bindings : NinjectModule
{
public override void Load()
{
Bind<IProcessorFactory>().ToMethod(context => new ProcessorFactoryA(() => context.Kernel.Get<ProcessorX>()));
Bind<IProcessorFactory>().ToMethod(context => new ProcessorFactoryB(() => context.Kernel.Get<ProcessorY>()));
Bind<IProcessorFactory>().ToMethod(context => new ProcessorFactoryC(() => context.Kernel.Get<ProcessorZ>()));
// Note that item type D is handled by processor X
Bind<IProcessorFactory>().ToMethod(context => new ProcessorFactoryD(() => context.Kernel.Get<ProcessorX>()));
}
}
I made a .NET fiddle with the full working code: http://dotnetfiddle.net/aD9E2y.
It has an error when you try to run the fiddle, but you can just grab the code into a .NET console project and it runs.
Some people don't like them, but I've used T4 templates to do things like automatically generating the processor factory classes using reflection. The bindings will still have to be manually created, however, because the association between item type and processor can't be inferred.

Ninject Contextual Binding at runtime depending on a specific value [duplicate]

If I have the following code:
public class RobotNavigationService : IRobotNavigationService {
public RobotNavigationService(IRobotFactory robotFactory) {
//...
}
}
public class RobotFactory : IRobotFactory {
public IRobot Create(string nameOfRobot) {
if (name == "Maximilian") {
return new KillerRobot();
} else {
return new StandardRobot();
}
}
}
My question is what is the proper way to do Inversion of Control here? I don't want to add the KillerRobot and StandardRobot concretes to the Factory class do I? And I don't want to bring them in via a IoC.Get<> right? bc that would be Service Location not true IoC right? Is there a better way to approach the problem of switching the concrete at runtime?
For your sample, you have a perfectly fine factory implementation and I wouldn't change anything.
However, I suspect that your KillerRobot and StandardRobot classes actually have dependencies of their own. I agree that you don't want to expose your IoC container to the RobotFactory.
One option is to use the ninject factory extension:
https://github.com/ninject/ninject.extensions.factory/wiki
It gives you two ways to inject factories - by interface, and by injecting a Func which returns an IRobot (or whatever).
Sample for interface based factory creation: https://github.com/ninject/ninject.extensions.factory/wiki/Factory-interface
Sample for func based: https://github.com/ninject/ninject.extensions.factory/wiki/Func
If you wanted, you could also do it by binding a func in your IoC Initialization code. Something like:
var factoryMethod = new Func<string, IRobot>(nameOfRobot =>
{
if (nameOfRobot == "Maximilian")
{
return _ninjectKernel.Get<KillerRobot>();
}
else
{
return _ninjectKernel.Get<StandardRobot>();
}
});
_ninjectKernel.Bind<Func<string, IRobot>>().ToConstant(factoryMethod);
Your navigation service could then look like:
public class RobotNavigationService
{
public RobotNavigationService(Func<string, IRobot> robotFactory)
{
var killer = robotFactory("Maximilian");
var standard = robotFactory("");
}
}
Of course, the problem with this approach is that you're writing factory methods right inside your IoC Initialization - perhaps not the best tradeoff...
The factory extension attempts to solve this by giving you several convention-based approaches - thus allowing you to retain normal DI chaining with the addition of context-sensitive dependencies.
The way you should do:
kernel.Bind<IRobot>().To<KillingRobot>("maximilliam");
kernel.Bind<IRobot>().To<StandardRobot>("standard");
kernel.Bind<IRobotFactory>().ToFactory();
public interface IRobotFactory
{
IRobot Create(string name);
}
But this way I think you lose the null name, so when calling IRobotFactory.Create you must ensure the correct name is sent via parameter.
When using ToFactory() in interface binding, all it does is create a proxy using Castle (or dynamic proxy) that receives an IResolutionRoot and calls the Get().
I don't want to add the KillerRobot and StandardRobot concretes to the Factory class do I?
I would suggest that you probably do. What would the purpose of a factory be if not to instantiate concrete objects? I think I can see where you're coming from - if IRobot describes a contract, shouldn't the injection container be responsible for creating it? Isn't that what containers are for?
Perhaps. However, returning concrete factories responsible for newing objects seems to be a pretty standard pattern in the IoC world. I don't think it's against the principle to have a concrete factory doing some actual work.
I was looking for a way to clean up a massive switch statement that returned a C# class to do some work (code smell here).
I didn't want to explicitly map each interface to its concrete implementation in the ninject module (essentially a mimic of lengthy switch case, but in a diff file) so I setup the module to bind all the interfaces automatically:
public class FactoryModule: NinjectModule
{
public override void Load()
{
Kernel.Bind(x => x.FromThisAssembly()
.IncludingNonPublicTypes()
.SelectAllClasses()
.InNamespaceOf<FactoryModule>()
.BindAllInterfaces()
.Configure(b => b.InSingletonScope()));
}
}
Then create the factory class, implementing the StandardKernal which will Get the specified interfaces and their implementations via a singleton instance using an IKernal:
public class CarFactoryKernel : StandardKernel, ICarFactoryKernel{
public static readonly ICarFactoryKernel _instance = new CarFactoryKernel();
public static ICarFactoryKernel Instance { get => _instance; }
private CarFactoryKernel()
{
var carFactoryModeule = new List<INinjectModule> { new FactoryModule() };
Load(carFactoryModeule);
}
public ICar GetCarFromFactory(string name)
{
var cars = this.GetAll<ICar>();
foreach (var car in cars)
{
if (car.CarModel == name)
{
return car;
}
}
return null;
}
}
public interface ICarFactoryKernel : IKernel
{
ICar GetCarFromFactory(string name);
}
Then your StandardKernel implementation can get at any interface by the identifier of you choice on the interface decorating your class.
e.g.:
public interface ICar
{
string CarModel { get; }
string Drive { get; }
string Reverse { get; }
}
public class Lamborghini : ICar
{
private string _carmodel;
public string CarModel { get => _carmodel; }
public string Drive => "Drive the Lamborghini forward!";
public string Reverse => "Drive the Lamborghini backward!";
public Lamborghini()
{
_carmodel = "Lamborghini";
}
}
Usage:
[Test]
public void TestDependencyInjection()
{
var ferrari = CarFactoryKernel.Instance.GetCarFromFactory("Ferrari");
Assert.That(ferrari, Is.Not.Null);
Assert.That(ferrari, Is.Not.Null.And.InstanceOf(typeof(Ferrari)));
Assert.AreEqual("Drive the Ferrari forward!", ferrari.Drive);
Assert.AreEqual("Drive the Ferrari backward!", ferrari.Reverse);
var lambo = CarFactoryKernel.Instance.GetCarFromFactory("Lamborghini");
Assert.That(lambo, Is.Not.Null);
Assert.That(lambo, Is.Not.Null.And.InstanceOf(typeof(Lamborghini)));
Assert.AreEqual("Drive the Lamborghini forward!", lambo.Drive);
Assert.AreEqual("Drive the Lamborghini backward!", lambo.Reverse);
}

Factory Interface Create Method with object Argument

I have a question about creating a factory interface with a create method that can cater for accepting different argument types depending on the implementation.
To give you a bit more background, I am using dependency in injection in a project, and require stateful objects to be generated at runtime - therefore I am injecting factories (rather than the objects themselves) to create these stateful objects. The problem I have come across is that, for some interfaces, the concrete implementations simply cannot have the same constructor argument types, and so the factories that create an instance of these interfaces require almost 'dynamic' arguments to be passed to the create method.
I have been going over this for a couple of days, and the following is the best solution I could come up with (namely, passing an object to the factory create method and casting it in the concrete implementation of the factory). I am really looking for feedback from people who have come across this scenario before, to hear what they came up with, and whether or not the solution I am proposing below is acceptable.
Apologies if this is missing any information, and many thanks in advance!
//
// Types...
//
interface IDataStore
{
List<string> GetItems();
}
public class XmlDataStore : IDataStore
{
public XmlDataStore(XmlDocument xmlDoc)
{
// Initialise from XML Document...
}
public List<string> GetItems()
{
// Get Items from XML Doc...
}
}
public class SQLDataStore : IDataStore
{
public SQLDataStore(SqlConnection conn)
{
// Initialise from SqlConnection...
}
public List<string> GetItems()
{
// Get Items from Database Doc...
}
}
//
// Factories...
//
interface IDataStoreFactory
{
IDataStore Create(object obj);
}
class XmlDataStoreFactory : IDataStore
{
IDataStore Create(object obj)
{
// Cast to XmlDocument
return new XmlDataStore((XmlDocument)obj);
}
}
class SQLDataStoreFactory : IDataStore
{
IDataStore Create(object obj)
{
// Cast to SqlConnection
return new SQLDataStore((SqlConnection)obj);
}
}
Based on this comment you need one factory which produces several types of IDataStore. You could accomplish by creating a open generic factory method in the singleton factory instance.
interface IDataStore<TStoreType>
{
void SetBaseType(TStoreType obj);
List<string> GetItems();
}
interface IDataStoreFactory
{
IDataStore<TStoreType> Create<TStoreType>(TStoreType obj)
}
class DataStoreFactory : IDataStoreFactory
{
public IDataStore<TStoreType> Create<TStoreType>(TStoreType obj)
{
if (obj.GetType() == typeof(SqlConnection))
{
var store = new SQLDataStore((SqlConnection)(Object)obj);
return (IDataStore<TStoreType>)store;
}
if (obj.GetType() == typeof(XmlDocument))
{ //... and so on }
}
}
class SQLDataStore : IDataStore<SqlConnection>
{
private readonly SqlConnection connection;
public SQLDataStore(SqlConnection connection)
{
this.connection = connection;
}
public List<string> GetItems() { return new List<string>(); }
}
You can use this factory like this:
var factory = new DataStoreFactory();
var sqlDatastore = factory.Create(new SqlConnection());
var xmlDatastore = factory.Create(new XmlDocument());
Your datastore factory would become a lot less complex if you would use a DI container. You could inject the container in the factory and retrieve your instances directly from the container, which would typically build your instances from bottom to top, including there own dependencies, lifetime management and so on. But be very carefull with this approach, it is the first step to using the service locator pattern which is an anti pattern
Not really sure if I understand your question correctly but to me it sounds a little odd to have factory instances which you use for the creation of your statefull objects as you call them.
To directly answer your question: generics are your solution. You rinterface becomes an open generic abstraction:
interface IDataStore<TStoreType>
{
List<string> GetItems();
}
interface IDataStoreFactory<TStoreType>
{
IDataStore<TStoreType> Create(TStoreType obj);
}
and your factory classes will look like this:
class XmlDataStoreFactory : IDataStoreFactory<XmlDocument>
{
IDataStore<XmlDocument> Create(XmlDocument document)
{
return new XmlDataStore(document);
}
}
class SQLDataStoreFactory : IDataStoreFactory<SqlConnection>
{
IDataStore<SqlConnection> Create(SqlConnection connection)
{
return new SQLDataStore(connection);
}
}
This will work, but from the examples you give I got the impression you're using factories throughout your codebase. Maybe I'm wrong on this point, but look at your design and minimize the number of factories. Needing a factory means mixing data with behaviour and this will always, eventually, get you into trouble.
For example, let's say you have some kind of service which adds the current user to a audit log when he logs in. This service offcourse needs the current user which is a typical example of runtime data (or contextual data). But instead of:
public class AuditLogService
{
public void AddApplicationSignIn(User user)
{
//... add user to some log
}
}
I know this is not a good example because you actually wouldn't need a factory for this class, but with the next code example you'll get the point:
public class AuditLogService
{
private readonly IUserContext userContext;
public AuditLogService(IUserContext userContext)
{
this.userContext = userContext;
}
public void AddApplicationSignIn()
{
var user = this.userContext.GetCurrentUser();
//... add user to some log
}
}
So by splitting data from behaviour you rule out the need for factories. And admitted there are cases where a factory is the best solution. I do think an IDataStore is not something you need a factory for.
For a good blog on splitting data and behaviour read here

Categories

Resources