I'm having a hard time understanding the implementation of client code with the factory method. I understand the overall use of Abstract Factories but my issue is I want the Factory to figure out the correct object to instantiate at runtime, but every implementation I see involves passing an enum or some other value to the constructor.
This is my current design
using System;
namespace FactoryTest.Jobs
{
public class ExchangeProvider1 : IExchangeProvider
{
public void Buy()
{
Console.WriteLine("Buying on Exchange1!");
}
}
}
using System;
namespace FactoryTest.Jobs
{
public class ExchangeProvider2 : IExchangeProvider
{
public void Buy()
{
Console.WriteLine("Buying on Exchange2");
}
}
}
public interface IExchangeFactory
{
}
public interface IExchangeProvider
{
void Buy();
}
public class ExchangeFactory : IExchangeFactory
{
public static IExchangeProvider CreateExchange<T>() where T : IExchangeProvider
{
return Activator.CreateInstance<T>();
}
public static IExchangeProvider CreateExchange(string exchangeName)
{
return (IExchangeProvider) Activator.CreateInstance<IExchangeProvider>();
}
}
The problem is that I'm trying to have the factory build the correct provider based on details the user fills out in a web form. On hitting create I want to the factory to instantiate the correct provider and run the correct logic. But with this implementation Im forced to do something like
var provider = ExchangeFactory.CreateExchange<Exchange1>();
When I really want to be able to get the Exchange Type from the user at runtime from the web form and pass it to the factory
//Receive IExchangeType from user submitting web form
var provider = ExchangeFactory.CreateExchange<IExchangeType>();
Is this possible? I'm wondering (or the correct solution), or if I'm on the right track but am definitely hindered by a gap in knowledge.
Generally you shouldn't tell the factory which concrete type to create. You should give it the information it needs to make that decision by itself. Now, I'm not saying that this can't be a 1:1 relationship, just that the caller shouldn't tell the factory to make a specific concrete type.
Imagine you have a Student object with a Grade property. You also have a factory which produces ISchool, and concrete implementations ElementarySchool, MiddleSchool, and HighSchool. Now you could have 3 methods: CreateElementarySchool(), CreateMiddleSchool() and CreateHighSchool(), but then the caller has to decide which one it wants.
A better approach is to have a method which uses some information to create the the school. For example: CreateSchoolForGrade(grade). Internally, the factory will have logic which works out which concrete type matches the grade.
In your case, if you have a set of 2 types to choose from on a webform, you could accept the type (let's say the options are Empire or Rebels). You could have an enum:
public enum Faction
{
Empire,
Rebels
}
and then a factory method:
public IFaction CreateFaction(Faction faction)
{
switch (faction)
{
case Faction.Empire:
return new EmpireFaction();
case Faction.Rebels:
return new RebelsFaction();
default:
throw new NotImplementedException();
}
}
Now, imagine that you retire EmpireFaction, replacing it with EmpireFactionV2. You only need to modify your factory, and the caller doesn't care:
public IFaction CreateFaction(Faction faction)
{
switch (faction)
{
case Faction.Empire:
return new EmpireFactionV2();
case Faction.Rebels:
return new RebelsFaction();
default:
throw new NotImplementedException();
}
}
As noted in the comments the other answer is a violation of O/C Principle (and a bit of Single Responsibility Principle (SRP)) of SOLID.
A more dynamic approach is to inject all instances of the exchange and pick the correct one. Bellow example is based on the class name (not full-qualifed name, but that cane easily be changed).
public interface IExchange
{
void Buy();
}
public class Exchange1 : IExchange
{
public void Buy() => Console.WriteLine("Buying on Exchange1");
}
public class Exchange2 : IExchange
{
public void Buy() => Console.WriteLine("Buying on Exchange2");
}
public interface IExchangeFactory
{
IExchange CreateExchange(string exchangeName);
}
// All exchanges are instantiated and injected
public class ExchangeFactory : IExchangeFactory
{
private readonly IEnumerable<IExchange> exchanges;
public ExchangeFactory(IEnumerable<IExchange> exchanges)
{
this.exchanges = exchanges ?? throw new ArgumentNullException(nameof(exchanges));
}
public IExchange CreateExchange(string exchangeName)
{
var exchange = exchanges.FirstOrDefault(e => e.GetType().Name == exchangeName);
if(exchange==null)
throw new ArgumentException($"No Exchange found for '{exchangeName}'.");
return exchange;
}
}
It can easily be extended by registering further implementation with the DI, w/o any code changes on the factory
service.AddScoped<IExchange, Exchange3>();
service.AddScoped<IExchange, Exchange4>();
In high performance scenarios (a couple of 1000 requests per second) where the injected services are scoped/transient or the memory/GC pressure on creating this extra instances is high, you can use the provider pattern to only create the exchange that's really required:
public interface IExchangeProvider
{
IExchange CreateExchange(string exchangeName);
}
public class Exchange1Provider : IExchangeProvider
{
public IExchange CreateExchange(string exchangeName)
{
if(exchangeName == nameof(Exchange1))
{
// new it, resolve it from DI, use activation whatever suits your need
return new Exchange1();
}
return null;
}
}
public class Exchange2Provider : IExchangeProvider
{
public IExchange CreateExchange(string exchangeName)
{
if (exchangeName == nameof(Exchange2))
{
// new it, resolve it from DI, use activation whatever suits your need
return new Exchange1();
}
return null;
}
}
public class LazyExchangeFactory : IExchangeFactory
{
private readonly IEnumerable<IExchangeProvider> exchangeProviders;
public LazyExchangeFactory(IEnumerable<IExchangeProvider> exchangeProviders)
{
this.exchangeProviders = exchangeProviders ?? throw new ArgumentNullException(nameof(exchangeProviders));
}
public IExchange CreateExchange(string exchangeName)
{
// This approach is lazy. The providers could be singletons etc. (avoids allocations)
// and new instance will only be created if the parameters are matching
foreach (IExchangeProvider provider in exchangeProviders)
{
IExchange exchange = provider.CreateExchange(exchangeName);
// if the provider couldn't find a matcing exchange, try next provider
if (exchange != null)
{
return exchange;
}
}
throw new ArgumentException($"No Exchange found for '{exchangeName}'.");
}
}
This approach is similar to the first, with the exception that you are extending it by adding new IExchangeProviders. Both approaches allow you to extend the exchanges w/o a change on ExchangeFactory (or in high performance scenarios LazyExchangeFactory)
Related
We are building an application where we have to have both old and new version to work side by side (V1 is old and V2 is new). Now to handle new flow we are using same old interfaces with everything being the same and differs only in functionality, hence now we have to define a named instance in-order to resolve the instances for new flow.
In the process teams have started using Service Factory Pattern as shown below
class DataProcessor
{
private readonly IDataManager _dataManager;
public DataProcessor(IServiceFactory serviceFactory)
{
_dataManager = serviceFactory.GetInstance<IDataManager>();
}
public void Execute()
{
_dataManager.Run();
}
}
Service Factory Class
public class ServiceFactory : IServiceFactory
{
private readonly IFeatureEvaluator _featureEvaluator;
public ServiceFactory(IFeatureEvaluator featureEvaluator)
{
_featureEvaluator = featureEvaluator;
}
public T GetInstance<T>()
{
if (_featureEvaluator.IsEnabled<"V2">())
{
return ObjectFactory.GetInstance<T>("V2")
}
return ObjectFactory.GetInstance<T>();
}
}
Since Service Factory is anti-pattern and also it creates lot of complexities in retiring the old flow in future, I would want a way to initialize the dependencies at the container(structuremap ioc) itself or to work in a "Pure DI" way so that we can avoid headache. Any idea on how to tackle this.
Update:
IDataManager Implementation
public interface IDataManager
{
void Run();
}
public class OldFlow : IDataManager
{
public void Run()
{
//
}
}
public class NewFlow : IDataManager
{
public void Run()
{
//
}
}
IDataManager has 2 implementations and resolving the instance should be based on _featureEvaluator, if V2 flow then "newflow" should be instantiated else "old flow" instance
Why don't you just inject the dependency you need?
public class DataProcessor
{
private readonly IDataManager _dataManager;
public DataProcessor(IDataManager dataManager)
{
_dataManager = dataManager;
}
public void Execute()
{
_dataManager.Run();
}
}
In your Composition Root you can conditionally compose DataProcessor with the implementation of IDataManager you'd like:
public DataProcessor CreateDataProcessor()
{
if (_featureEvaluator.IsEnabled<"V2">())
{
IDataManager dm = new NewFlow();
return new DataProcessor(dm);
}
IDataManager dm = new OldFlow();
return new DataProcessor(dm);
}
This seems to be similar to feature toggles. Why, by the way, is _featureEvaluator an interface? Wouldn't a bool suffice?
I'm trying to learn somethings about Dependency Injection and Specification Pattern.
If I have this scenario: I have three methods and they have different validation rules. This rules are validated by Specifications. So... My class must receive on the constructor these Specifications like this?
public PostService(IRepositorio rep, ISpecificationSave ss, SpecificationGet g, ISpecificationDelete sd) {
// do things...
}
But if is this correct, when I add a new method, I need to change de constructor to receive more one Specification?
Or, even using Dependency Inject, is better, in this case, create an instance of Specification on method how's use the Specification like that:
public void DoSomeThing(MyObject object) {
Specification<MyObject> specification = new Specification<MyObject>();
// do things...
}
I know the question is simple for some one of you, but I'm trying to learn those kinds of patterns yet.
You can use these Specifications in each validator by them adding one by one in your class, using Specitication Pattern, as follow:
public Class Class1 : IClass1 {
private List<ISpecification> contents;
private List<ISpecification> specializations;
public List GetContents() {
return contents;
}
public Set GetFeatures() {
return specifications;
}
public Class1() {
features = new List<ISpecification>(){//put specializations who belongs this class here};
specialications = new List<ISpecification>();
}
public boolean Validator1() {
foreach(ISpecification as spec in this.specializations) {
if (!spec.GetSpecification().IsSatisfiedBy(this))
return false;
}
return true;
}
}
public class Specification1 : ISpecification {
private object requiredFeature;
public Specification1(object feature) {
requiredFeature = feature;
}
public boolean IsSatisfiedBy(IClass class) {
return class.GetFeatures().contains(requiredFeature);
}
}
Then, you can add specifications in your application by:
IClass1 class = new Class1();
class.GetFeatures().add(new Specialization1(// some feature));
class.GetFeatures().add(new Specialization2(// some feature));
class.GetFeatures().add(new Specialization3(// some feature));
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);
}
I am planning to solve a particular problem by using abstract factory pattern. I was successful in implementing factory pattern but not able to extend factory pattern to Abstract factory
I have two different places where exception details can be stored
File system
Database
I have used factory pattern to abstract away object creation details from client
Interface
public interface ILogException
{
void LogException();
}
FileSystemLogger
public class FileExceptionLogger : ILogException
{
public void LogException()
{
Console.WriteLine("File Exception Logger");
}
}
DBSystemLogger
public class DBExceptionLogger : ILogException
{
public void LogException()
{
Console.WriteLine("DB Exception Logger");
}
}
Factory Implementation
public class ExceptionFactory
{
const int i = 1;
public static ILogException GetFactory()
{
if (i == 1)
{
return new FileExceptionLogger();
}
else if (i == 2)
{
return new DBExceptionLogger();
}
else
{
return new ServiceExcetionLogger();
}
}
}
I know this is not the best of implementation but i plan to change it.
Now FileSystemLogger and DatabaseLogger are in itself a factory, I want to group following implementation under FileSystemLogger and DatabaseLogger so that the client can have FileSystemLoggerFactory and DatabaseLoggerFactory
FileSystemLogger
FlatFileSystemLogger
XMLFileSystemLogger
DatabaseLogger
SQLSERVERLogger
OracleLogger
How should i proceed with defining FileSystemLoggerFactory and DatabaseLoggerFactory?
If you want, you could make the factory method a generic one:
public static ILogException GetFactory<T>() where T : ILogException
{
return (ILogException)Activator.CreateInstance<T>();
}
Call it like:
ILogException logger = ExceptionFactory.GetFactory<FileExceptionLogger>();
You also might want to take a look at a dependency injection library like NInject, Unity, etc. These can simplify this kind of problem, allowing you to centralize the logic for which interfaces get bound to which implementations. (Ie, you can bind an implementation in the application or request scope.)
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.