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
Related
I am trying to get IoC working with Unity in C# with the idea of a passing a wrapper/composite class into the children.
The top level class that composes multiple classes provides some common functionality that the composed classes require access to.
To illustrate:
// The top composite class
public class Context : IContext {
public ISomething SomethingProcessor { get; }
public IAnother AnotherProcessor { get; }
public Context(ISomething something, IAnother another) {
this.SomethingProcessor = something;
this.AnotherProcessor = processor;
}
// A function that individual classes need access to, which itself calls one of the children.
public string GetCommonData() {
return this.AnotherProcessor.GetMyData();
}
}
public class Something : ISomething {
private _wrapper;
public Something(IContext context) {
this._wrapper = context;
}
// This class has no knowledge of IAnother, and requests data from the master/top class, which knows where to look for whatever.
public void Do() {
Console.WriteLine(_wrapper.GetCommonData());
}
}
public class Another : IAnother {
public string GetMyData() {
return "Foo";
}
}
If you didn't use IoC, it's easy, as the constructor for the Context class becomes:
public Context() {
this.SomethingProcessor = new Processor(this);
this.AnotherProcessor = new Another();
}
But when you're using IoC, the idea of "this" doesn't exist yet because it is yet to be constructed by the injector. Instead what you have a is a circular dependency.
container.RegisterType<ISomething, Something>();
container.RegisterType<IAnother, Another>();
container.RegisterType<IContext, Context>();
var cxt = container.Resolve<IContext>(); // StackOverflowException
The above example has been greatly simplified to illustrate the concept. I'm struggling to find the "best practice" way of dealing with this kind of structure to enable IOC.
Factory pattern is a way construct an object based on other dependencies or logical choices.
Factory Method: "Define an interface for creating an object, but let
the classes which implement the interface decide which class to
instantiate. The Factory method lets a class defer instantiation to
subclasses" (c) GoF.
Lots of construction.. hence the name Factory Pattern
A crude code sample that could be used with DI
public class ContextFactory : IContextFactory {
_anotherProcessor = anotherProcessor;
public ContextFactory(IAnotherProcessor anotherProcessor) {
//you can leverage DI here to get dependancies
}
public IContext Create(){
Context factoryCreatedContext = new Context();
factoryCreatedContext.SomethingProcessor = new SomethingProcessor(factoryCreatedContext )
factoryCreatedContext.AnotherProcessor = _anotherProcessor;
//You can even decide here to use other implementation based on some dependencies. Useful for things like feature flags.. etc.
return context;
}
}
You can get away with this, maybe? - but there is still the cyclic reference issue here and I would never commit this kind of code.
The problem here you need to concentrate on Inversion Of Control of that GetCommonData
Your SomethingProcessor should not rely on methods in another class. This is where In Inheritance could be used but Inheritance can become very complicated very quickly.
The best way forward is to Identify the ONE thing that is needed by both or many other places and break that out into a new Dependency. That is how you Invert Control.
TIP:
Don't overdo Interfaces- Use Interfaces where you think you will be working with Polymorphism, such as a collection of different objects that must promise you they have implemented a specific method/property. Otherwise you are over using Interfaces and increasing complexity. DI doesn't have to use Interfaces it can be a concrete implementation. Interfaces on Repositories are a good use since you can switch Databases out easily but Interfaces a factory like this is not really needed.
I don't know the name of this pattern, or even if it is a bad or good practice, but you can solve your problem of "double-binding" by creating a method to bind the "IContext", instead of doing it in the constructor.
For instance,
1) ISomething has a void BindContext(IContext context) method
2) You implement it as such :
class Something : ISomething
{
IContext _wrapper;
// ... nothing in constructor
public void BindContext(IContext context)
{
_wrapper = context;
}
}
3) Remove the IContext dependency injection in Something constructor.
And you call it from the context constructor :
public Context(ISomething something, IAnother another) {
this.SomethingProcessor = something;
this.SomethingProcessor.BindContext(this);
// same for IAnother
}
And you do the same for IAnother. You could even extract some common interface "IBindContext" to make things a beat more "DRY" (Don't Repeat yourself) and make IAnother and ISomething inherit from it.
Not tested, and again : not sure it's the best way to do such dependency design. I'll be glad if there is another answer which gives a state-of-the-art insight about this.
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);
}
Let's say I want to build a list of strings (Which is not the real scenario case, but sounds simpler to explain).
I'd have an interface for my list of strings factory that would look like this
public interface IStringsListFactory{
List<string> Create();
}
But lets say one of my concrete factory would require to get this list of string from a file/database etc..
public class StringsListFromFile : IStringsListFactory{
private StreamReader _streamReader;
public StringsListFromFile(StreamReader sr) //StreamReader is just an example.
{
_streamReader = sr;
}
public List<string> Create(){
///recover the strings using my stream reader...
}
}
I know this approach would work, but I was wondering if it breaks the Factory Pattern to pass parameters to the factory's constructor so I wouldn't break my interface. Are there any counterparts to doing this? Is there another solution I didn't think of? Am I asking too many questions!?! (Yeah, I know the answer to this one!)
Parameter in constructor, and constructor itself, should only do one and only one job to do: that is registering dependency. Sometimes, it is needed to "inject" the dependency to factory, as described at abstract factory pattern by Mark Seeman in this answer.
public class ProfileRepositoryFactory : IProfileRepositoryFactory
{
private readonly IProfileRepository aRepository;
private readonly IProfileRepository bRepository;
public ProfileRepositoryFactory(IProfileRepository aRepository,
IProfileRepository bRepository)
{
if(aRepository == null)
{
throw new ArgumentNullException("aRepository");
}
if(bRepository == null)
{
throw new ArgumentNullException("bRepository");
}
this.aRepository = aRepository;
this.bRepository = bRepository;
}
public IProfileRepository Create(string profileType)
{
if(profileType == "A")
{
return this.aRepository;
}
if(profileType == "B")
{
return this.bRepository;
}
// and so on...
}
}
It is valid in that case, but not in your case because:
It makes your factory have state
It makes your factory more flexible if the parameter (stream) injected as method parameter
public class StringsListFromFile : IStringsListFactory{
public List<string> Create(StreamReader sr){
///recover the strings using my stream reader...
}
}
If your interface should be flexible for the input, use generic instead
additionally, it is better to return IEnumerable<string> instead of List<string>
You could abstract away the implementation of whatever retrieves it. I would also personally pass it through into the method instead of the constructor:
public interface IFactoryDataSourceProvider<T> {
IList<T> GetData();
}
public class IStringListFactory {
public IList<string> Create(IFactoryDataSourceProvider<string> provider) {
return _provider.GetData();
}
}
Then perhaps:
class StreamReaderDataProvider : IFactoryDataSourceProvider<string> {
public IList<string> GetData() {
using (var streamReader = new StreamReader( ... )) {
return streamReader.ReadAllLines(); // etc.
}
}
}
var list = factory.Create(new StreamReaderDataSourceProvider());
This all seems silly for such a small sample.. but I assume this isn't quite as small as your example is.
Factory Pattern forces you to use Default Constructor.
Using a parametric constructor violates the idea of using factory pattern since the object will not return the valid state to the caller class. In your case, you have to initialize them after the factory class call. This will duplicate your code and the idea of using the factory pattern is to avoid the code duplication.
But again I am not familiar with the whole scenario. But as per your set up shown here you should use a method in place of Parametric Constructor.
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;
}
I am doing some research on design pattern implementation variants, i have come across and read some examples implemented here http://www.codeproject.com/Articles/37547/Exploring-Factory-Pattern and http://www.oodesign.com/factory-pattern.html. My focus of concern is when implementing factory pattern without reflection . the stated articles said that we need to register objects not classes which seems fine and logical to me but when seeing the implementation i see the duplication of objects e.g in the code below
// Factory pattern method to create the product
public IRoomType CreateProduct(RoomTypes Roomtype)
{
IRoomType room = null;
if (registeredProducts.Contains(Roomtype))
{
room = (IRoomType)registeredProducts[Roomtype];
room.createProduct();
}
if (room == null) { return room; }
else { return null; }
}
// implementation of concrete product
class NonACRoom : IRoomType
{
public static void RegisterProduct()
{
RoomFactory.Instance().RegisterProduct(new NonACRoom(), RoomTypes.NonAcRoom);
}
public void getDetails()
{
Console.WriteLine("I am an NON AC Room");
}
public IRoomType createProduct()
{
return new NonACRoom();
}
}
the method RegisterProduct is used for self registeration, we have to call it anyways before creating factory object i.e before some where in the main class of the client or anywhere applicable that ensure its calling. below is we are creating a new product and in the method above we are creating again a new product which seems non sense. any body comment on that
I have done something similar to this in the past. This is essentially what I came up with (and also doing away with the whole "Type" enumeration):
public interface ICreator
{
IPart Create();
}
public interface IPart
{
// Part interface methods
}
// a sample creator/part
public PositionPartCreator : ICreator
{
public IPart Create() { return new PositionPart(); }
}
public PositionPart : IPart
{
// implementation
}
Now we have the factory itself:
public sealed class PartFactory
{
private Dictionary<Type, IPartCreator> creators_ = new Dictionary<Type, IPartCreator>();
// registration (note, we use the type system!)
public void RegisterCreator<T>(IPartCreator creator) where T : IPart
{
creators_[typeof(T)] = creator;
}
public T CreatePart<T>() where T: IPart
{
if(creators_.ContainsKey(typeof(T))
return creators_[typeof(T)].Create();
return default(T);
}
}
This essentially does away with the need for a "type" enumeration, and makes things really easy to work with:
PartFactory factory = new PartFactory();
factory.RegisterCreator<PositionPart>(new PositionPartCreator());
// all your other registrations
// ... later
IPart p = factory.CreatePart<PositionPart>();
The first creation is used to give something to work on to RegisterProduct. Probably, the cost of that object is neglectable. It's done during initialization and won't matter much.
This instance is required though because in C# you need an object to call createProduct on. This is because you can't use reflection to store a reference to a type instead of a reference to an object.