I'm implementing a factory pattern that looks as follows.
public class FeedFactory
{
#region Singleton Pattern
//..
#endregion
private static Feed[] _factory = new Feed[(int)FeedType.Total];
public void RegisterFeed(FeedType feedType,Feed feed)
{
if (_factory[(int)feedType] == null)
{
_factory[(int)feedType] = feed;
}
else
{
// already registered
}
}
public Feed GetFeed(FeedType feedType)
{
return _factory[(int)feedType];
}
}
Here, Feed is an abstract class from which the different classes inherit. How can I register the different classes? Is it possible to do it from their constructor?
This is not a factory pattern. A factory will always have some constructor logic in it, at least one new. That's the idea of a factory: the caller doesn't have to worry about how objects are created. This is a singleton repository.
So first of all, instead of using an array, you should be having a type indexed dictionary.
private static Dictionary<Type, Feed> _singletons = new Dictionary<Type, Feed>();
After that, you don't need a register method. The dictionary should be filled automatically when you retrieve singletons.
Now I suppose your Feed class has a default constructor without arguments. In that case, you can implement a factory method directly from the abstract class Feed. We're going to use some generics here, because it allows you to control inheritance:
public abstract class Feed
{
public static T GetInstance<T>() where T:Feed, new()
{
T instance = new T();
// TODO: Implement here other initializing behaviour
return instance;
}
}
Now back to your singleton repository.
public class FeedSingletonRepository
{
private static readonly object _padlock = new object();
private static Dictionary<Type, Feed> _singletons = new Dictionary<Type, Feed>();
public static T GetFeed<T>() where T:Feed
{
lock(_padlock)
{
if (!_singletons.ContainsKey(typeof(T))
{
_singletons[typeof(T)] = Feed.GetInstance<T>();
}
return (T)_singletons[typeof(T)];
}
}
}
Note that I included a threadsafe behaviour which is a good thing to do when you work with singletons.
Now if you want to get the singleton for a given type inheriting from Feed (let's call it SpecializedFeedType), all you have to do is:
var singleton = FeedSingletonRepository.GetFeed<SpecializedFeedType>();
or
SpecializedFeedType singleton = FeedSingletonRepository.GetFeed();
which is the same line with a slightly different syntax.
Edit2: changed some syntax errors.
Just as a side note -- as a factory is intended to wrap creation, it's a curious choice that you're creating objects and registering them with the factory. Is this more an object repository than a factory, or is there more to the class than I'm seeing?
If it is an object repository, then you might also find some extra inspiration in other questions, like this one.
When you call the RegisterFeed method you need to pass a concrete instance of a Feed class. So it is the responsibility of the caller to provide the concrete implementation.
Just register the type of the classes you want to create, then use Activator.CreateInstance to create instances of that type.
It should work this way:
private static Type[] _factory = new Type[(int)FeedType.Total];
public void RegisterFeed(FeedType feedType, Type type)
{
...
_factory[(int)feedType] = type;
...
}
public Feed GetFeed(FeedType feedType)
{
return Activator.CreateInstance(_factory[(int)feedType]) as Feed;
}
You can call RegisterFeed like the following:
RegisterFeed(FeedType.SomethingSpecial, typeof(MyDerivedSpecialFeed));
class FeedFactory {
public IFeedFactory GetFeedFactory(string type) {
switch(type) {
case "1": return new Feed1(); break;
case "2": return new Feed2(); break;
}
}
}
Note all Feeds Must implement an IFeedFactory interface and implement the method necessary.
//From the client
FeedFactory ff1 = new FeedFactory();
IFeedFactory obj = ff1.GetFeedFactory("1");
obj.ExecuteMethod();
Related
I'm still new to using Autofac and I'm bothered by the constructor injection method that I'm using. Here's the scenario:
I currently have two classes which inherits the IForms interface. Each of the classes has its own interface as well
public interface IForms
{
long CreateNewForm(FormData data);
FormData RetrieveFormById(long id);
}
public interface IFormA : IForms
{ }
public interface IFormB : IForms
{ }
Now I have a class which handles this which is like this:
public class ApplicationForms : IApplicationForms
{
private readonly IFormA _formA;
private readonly IFormB _formB;
public ApplicationForms(IFormA formA, IFormB formB)
{
_formA = formA;
_formB = formB;
}
public void SubmitApplicationForm(FormData data)
{
switch(data.FormType)
{
case FormType.FormA:
_formA.CreateNewForm(data);
break;
case FormType.FormB:
_formB.CreateNewForm(data);
break;
}
}
}
Now there's a possibility that there will be 2 more forms coming in (ex. FormC, FormD, FormE). What will happen here is that there will be 3 more constructor parameters in the ApplicationForms constructor.
Is there a way to like combine all the constructor parameters into one parameter? I can see that it will definitely look ugly in the end.
The problem you're describing is that you have many forms, but at runtime you need one specific form, and so you don't want to inject all of the forms. That might be a good scenario for an abstract factory.
We often represent the factory as an interface with a single method, but we can also do it with a delegate:
public delegate IForm GetFormByTypeFunction(FormType formType);
Now your class looks like this:
public class ApplicationForms : IApplicationForms
{
private readonly GetFormByTypeFunction _getFormByType;
public ApplicationForms(GetFormByTypeFunction getFormByType)
{
_getFormByType = getFormByType;
}
public void SubmitApplicationForm(FormData data)
{
var form = _getFormByType(data.FormType);
form.CreateNewForm(data);
}
}
Now the question is how to implement the factory. It might still have a switch statement or something that doesn't seem too elegant, but that's okay. The point of the factory is that however it works, the business of creating and/or selecting an implementation is moved out of the class that depends on the implementation.
You can register a delegate with Autofac like this:
builder.Register<GetFormByTypeFunction>(context => formType =>
{
switch (formType)
{
case FormType.Type1:
{
return context.Resolve<FormOne>();
}
case FormType.Type2:
{
return context.Resolve<FormTwo>();
}
default:
throw new InvalidOperationException("Unknown form type");
}
});
Now you don't need to resolve all of the IForm implementations up front because you can resolve the one you want directly from the container once you know which one you want.
That might seem "wrong" because you're resolving from the container. But you're not resolving directly from the container. You're depending on a factory. That factory can be replaced with any other implementation which means that your class does not depend on the container.
This sort of factory is also super easy to mock. Technically it's not even a mock. It's just an implementation of the factory that returns a mock.
var formMock = new Mock<IForm>();
var factory = new GetFormByTypeFunction(formType => formMock.Object);
Since there is a common IForms interface, then you can inject an enumeration.
This looks like a good candidate for strategy pattern.
I would suggest refactoring the base interface to be able to identify what type of form it is
public interface IForms {
FormType FormType { get; }
long CreateNewForm(FormData data);
FormData RetrieveFormById(long id);
}
and update the dependent class
public class ApplicationForms : IApplicationForms {
private readonly IEnumerable<IForms> forms;
public ApplicationForms(IEnumerable<IForms> forms) {
this.forms = forms;
}
public void SubmitApplicationForm(FormData data) {
var form = forms.FirstOrDefault(_ => _.FormType == data.FormType);
if(form != null)
form.CreateNewForm(data);
//...
}
}
This assumes that when registering the derived interfaces that you associate it with the base IForms interface.
var builder = new ContainerBuilder();
builder.RegisterType<FormA>().As<IForms>();
builder.RegisterType<FormB>().As<IForms>();
builder.RegisterType<FormC>().As<IForms>();
//...
Now no matter how many more forms are added the class can perform without modification.
I have several Get____Factory methods in my application and I'd like to consolidate them with generics, but I'm still adjusting C# and a) am not 100% sure generics are the right way to go and b) am still learning how C# handles generics.
I'll eventually have a dictionary/map of factory interfaces and their classes. Not only do I want to consolidate all of my factories into an easy-access method but I need to allow plugin authors a way to register their own (and have access to them this way).
I started with something like this:
Note: Eventually there will be a dictionary or way to map interfaces types to their implementations - the if/else conditions are ugly and temporary, but simply a way to test.
public T GetFactory<T>() where T : IFactory {
var t = typeof(T);
if (t.Equals(typeof(IRecipeFactory))) {
var factory = new RecipeFactory();
return factory;
}
else if (t.Equals(typeof(IItemFactory))) {
var factory = new ItemFactory();
return factory;
}
else if (t.Equals(typeof(ITileFactory))) {
var factory = new TileFactory();
return factory;
}
}
It fails with Cannot implicitly convert type 'RecipeFactory' to 'T', so this won't work. In the long run I won't have conditionals but will rather lookup the class by its type. However, neither will work until I can find a solution for the cast issue.
Based on other answers, I tried double-casting ((T) (object)) but that errors with InvalidCastException: Cannot cast from source type to destination type..
Either this is a poor architecture or I'm using the generics incorrectly.
Here is solution bit different from S.C.'s solution.
public static class FactoryService
{
private static readonly Dictionary<Type, Func<IFactory>> factories = new Dictionary<Type, Func<IFactory>>()
{
{ typeof(IRecipeFactory), () => new RecipeFactory() },
{ typeof(IItemFactory), () => new ItemFactory() },
{ typeof(ITileFactory), () => new TileFactory() }
};
public static T GetFactory<T>() where T : IFactory
{
T factory = default(T);
Type requestedType = typeof(T);
if (factories.ContainsKey(requestedType))
{
factory = (T)factories[requestedType].Invoke();
}
return factory;
}
}
public interface IFactory { }
public interface IRecipeFactory : IFactory { }
public interface IItemFactory : IFactory { }
public interface ITileFactory : IFactory { }
public class RecipeFactory : IRecipeFactory { }
public class ItemFactory : IItemFactory { }
public class TileFactory : ITileFactory { }
Then you use it like this:
IRecipeFactory rf = FactoryService.GetFactory<IRecipeFactory>();
Let me first say that you are actually looking at is a simple version of an Inversion of Control (IOC) framework. Take a look at Ninject or something similar because it's kernel and binding factory are pretty much exactly what you want. It even allows the attachment of metadata so you can have the same interface resolve to different implementations depending on the circumstances, which is really useful when you have a data layer that might need to pull from either a web data source or a cache data source, for instance. Most IOC frameworks also offer recursive dependency resolution, which means when some instances have constructors that require other dependencies, the same dependency resolution occurs all the way down the chain based on the mappings or default mappings that can be inferred.
Aside from that, to do what you're after yourself, you'll want to make use of Activator.CreateInstance which takes a type and will construct a new instance based on that. You are on the right track with your dictionary mappings. When you tie those two together, you don't need any conditional logic and you don't need to know ahead of time or care about what type is being requested. When you're feeling comfortable you can actually shorten the dependency resolution and instantiation to a single line if you wish.
Here is a fully working sample (from my 30 seconds of testing) that does what you want to to the best of my understanding:
using System;
using System.Collections.Generic;
namespace Generics
{
// create some dummy interfaces and implementations.
// make sure everything inherits from the same type to allow for
// a generic return statement
public interface IFactory
{
void DoStuff();
}
public interface IFactory1 : IFactory { }
public class Factory1 : IFactory1
{
public void DoStuff()
{
Console.WriteLine("Factory1");
}
}
public interface IFactory2 : IFactory { }
public class Factory2 : IFactory2
{
public void DoStuff()
{
Console.WriteLine("Factory2");
}
}
class Program
{
// create our binding mappings
IDictionary<Type, Type> bindings = new Dictionary<Type, Type>()
{
// expose a way for plugins/etc to add to this. that part is trivial.
{typeof(IFactory1), typeof(Factory1) },
{typeof(IFactory2), typeof(Factory2) }
};
// a method to actually resolve bindings based on expected types
public IFactory ResolveBinding<T>() where T : IFactory
{
Type requestedType = typeof(T);
if (requestedType != null && bindings.ContainsKey(requestedType))
{
// use the activator to generically create an instance
return (T) Activator.CreateInstance(bindings[requestedType]);
}
return null;
}
// test it out
static void Main(string[] args)
{
Program demo = new Program();
// test with two interfaces
demo.ResolveBinding<IFactory1>().DoStuff(); // prints out "Factory1"
demo.ResolveBinding<IFactory2>().DoStuff(); // prints out "Factory2"
Console.ReadKey();
}
}
}
You are going to want to cast the object to T on the way out since the method returns T. To do this cast you will have to make factory an IFactory
public T GetFactory<T>() where T : IFactory
{
var t = typeof(T);
if (t.Equals(typeof(IRecipeFactory)))
{
IFactory factory = new RecipeFactory();
return (T)factory;
}
if (t.Equals(typeof(IItemFactory)))
{
IFactory factory = new ItemFactory();
return (T)factory;
}
if (t.Equals(typeof(ITileFactory)))
{
IFactory factory = new TileFactory();
return (T)factory;
}
throw new InvalidOperationException("Type not supported");
}
Subject
This is simplified example of implementing a factory pattern in a way to restrict direct access to constructors and prevent illegal ways to create objects from other assemblies.
In other words I want to limit other developers to only be able to create their objects using this factory. (there are things must be done during object creation which is not specific to one object but related to all objects hence the reason)
Solution
I have this delegate which is used to create object instances inside my factory.
internal delegate T Instantiate<out T>(/*parameters*/) where T : Vehicle;
As you can see this delegate is internal, all constructors related to Vehicle and its sub-types are also internal.
internal interface IVehicle{/*...*/}
public class Vehicle
{
//constructor is not protected. so this cant be intertied from outside assembly.
internal Vehicle(/*parameters*/){ }
}
public class Car : Vehicle
{
internal Car(/*parameters*/) : base(/*parameters*/) { }
}
Now here is the trick.
/// <summary>
/// Choose from one of predefined containers to create your vehicle from factoy.
/// </summary>
/// <typeparam name="T">type of vehicle</typeparam>
public class InstanceContainer<T> where T : Vehicle
{
internal InstanceContainer(Instantiate<T> instance) // internal
{
GetInstance = instance;
}
// delegate which creates new instance of T
internal Instantiate<T> GetInstance { get; }
}
This makes others be able to choose their delegate but not access actual delegate. here are some options they can choose.
/// <summary>
/// Choose this to create car from factory.
/// </summary>
public static InstanceContainer<Car> CarInstance { get; } = new InstanceContainer<Car>(CreateCar);
private static readonly Instantiate<Car> CreateCar = (/*parameters*/) => new Car(/*parameters*/);
// ... others options like Plane, Ship etc
Example
Here is one of the methods to create an object from factory.
public static T CreateVehicle<T>(/*parameters,*/ InstanceContainer<T> instance) where T : Vehicle
{
T obj;
//...
// At some point:
obj = instance.GetInstance(/*parameters*/);
//...
return obj;
}
Now here is how to use it. (from other assemblies say create a Car)
VehicleFactory.CreateVehicle(/*parameters,*/ VehicleFactory.CarInstance);
This works fine, it complies fine and runs fine till now.
Note: VehicleFactory is public static class holding instances, methods, delegates...
Question
Now I want to make InstanceContainer co-variant so I can pass instances abstractly.
// turns long name into short one!
using VehicleInstance = Factories.VehicleFactory.InstanceContainer<Factories.Goods.Vehicle>
//...
//...
VehicleInstance instance;
// instance will be choosen based on some conditions. like this:
if(true)
instance = VehicleFactory.CarInstance; // we got magic co-variant here!
else
instance = VehicleFactory.PlaneInstance;
VehicleFactory.CreateVehicle(/*parameters,*/ instance);
Is there any way to make InstanceContainer co-variant but not expose its delegate to other assemblies?
This is what I have tried so far:
public interface IContainer<out T>
{
// empty!
}
internal class InstanceContainer<T> : IContainer<T> where T : Vehicle
{
internal InstanceContainer(Instance<T> instance)
{
GetInstance = instance;
}
internal Instance<T> GetInstance { get; }
}
This time IContainer is public interface and InstanceContainer is internal. that means we must use IContainer instead for safe access. little things must change:
// works fine!
public static IContainer<Car> CarInstance { get; } = new InstanceContainer<Car>(CreateCar);
public static T CreateVehicle<T>(/*parameters,*/ IContainer<T> instance)
{
T obj;
//...
// At some point:
obj = ((InstanceContainer<T>)instance).GetInstance(/*parameters*/); // runtime error.
//...
return obj;
}
Problem and Conclusion
The problem appears at runtime. we can not cast co-variant interface back to its actual class implementation.
Sorry for long question. but I know without subject, the answer for title would be pretty straight forward:
"You cant. because generic variants are pinned to interfaces. interfaces are pinned to public implements. it cant be internal. that's c# limit thing :("
I've also tried explicit implements but that does not work either. you basically end up with public interface and that will expose internal delegate anyway.
So is there better way to implement such factory pattern or am I using wrong design pattern? maybe I'm overthinking and solution is simple.
Thanks for giving your time and answer.
I would simplify your solution to this:
internal delegate Vehicle VehicleConstructor(string data, string type);
public static class Factory {
private static readonly Dictionary<Type, VehicleConstructor> _factories = new Dictionary<Type, VehicleConstructor>() {
{typeof(Car), (data, type) => new Car(data)},
{typeof(Plane), (data, type) => new Plane(data, type)}
};
public static T CreateVehicle<T>(string data, string type) where T : Vehicle {
if (!_factories.ContainsKey(typeof(T)))
throw new Exception("Cannot create Vehicle of type " + typeof(T).Name);
return (T) _factories[typeof(T)](data, type);
}
public static Vehicle CreateVehicle(Type vehicleType, string data, string type) {
if (!_factories.ContainsKey(vehicleType))
throw new Exception("Cannot create Vehicle of type " + vehicleType.Name);
return _factories[vehicleType](data, type);
}
}
Then you can do both this:
var car = Factory.CreateVehicle<Car>("data", "type");
And this:
var v = Factory.CreateVehicle(true ? typeof(Car) : typeof(Plane), "data", "type");
All examples which I found in general base on enumeration which provides to return the proper class. I need something which reacts in general on type of class and also is controlling constructors of new object by giving to it new parameters with each call.
Is it still factory method? Is it good solution? Can I play with design patterns in such way? Maybe there is better solution to provide?
using System;
namespace ConsoleApplication1
{
public abstract class Strategy
{
protected int Init;
private static int _initA = 3;
private static int _initB = 42;
public static Strategy StrategyFactory(Strategy strategyType)
{
var tempStrategyA = strategyType as StrategyA;
if (tempStrategyA != null)
{
_initA++;
return new StrategyA(_initA);
}
var tempStrategyB = strategyType as StrategyB;
if (tempStrategyB != null)
{
_initB = _initA * 2;
return new StrategyB(_initB);
}
throw new ArgumentException();
}
}
public class StrategyA : Strategy
{
public StrategyA(int init)
{
Init = init*2;
}
}
public class StrategyB : Strategy
{
public StrategyB(int init)
{
Init = init*3;
}
}
}
To me what it looks like is you actually want to have a different factory for each strategy. Factories are good if you want to either manage the lifetime of the objects the factory creates, or to manage dependencies / arguments for the construction of the various types.
Definition of strategy factories
interface IStrategyFactory
{
public Strategy Create(int value);
}
class StrategyAFactory : IStrategyFactory
{
public Strategy Create(int value)
{
return new StrategyA(value);
}
}
class StrategyBFactory : IStrategyFactory
{
public Strategy Create(int value)
{
return new StrategyB(value);
}
}
Usage
class MyController : ApiController
{
private IStrategyFactory _factory;
public MyController(IStrategyFactory factory)
{
_factory = factory;
}
public HttpResponseMessage Get(int value)
{
// here we don't care what exact strategy is used, this is good!
var strategy = _factory.Create(value);
var newValue = strategy.Calculate();
return new HttpResponseMessage(newValue);
}
}
This is a very strange factory method. See your factory method signature:
// "strategyType"? It's not a type, but an object reference
public static Strategy StrategyFactory(Strategy strategyType)
In .NET there's a class called Type which represents type metadata for some given type. You get it using typeof operator or Object.GetType() method.
Your factory method should be:
public static Strategy StrategyFactory(Type strategyType)
And you can instantiate a type using reflection:
Activator.CreateInstance(strategyType);
There's also a CreateInstance overload to give constructor arguments.
What about generics?
Since .NET 2.0 (we're talking about a lot of years ago!), .NET has generics. In summary, they provide a way to specify parameters which don't have a concrete type until a method or type is actually declared or used somewhere and provides which actual type will have the whole parameters.
For example, this would be a modern factory method:
// "where ..." is a generic constraint which defines that the given generic
// argument must be Strategy or a derived class of Strategy, and it must
// have a public parameterless constructor
public TStrategy Create<TStrategy>() where TStrategy : Strategy, new()
{
TStrategy strategy = new TStrategy();
// more stuff
return strategy;
}
And now you can use it this way:
MyStrategy strategy = StrategyFactory.Create<MyStrategy>();
I could give you a generics' master class, but this goes out of the scope of your question. Anyway I gave you a clue/hint about how you need to build a factory using the right tool. You can learn more about generics in MSDN.
How do I adapt an existing class of the form:
public class A
{
A(IDependency1 obj1, IDependency2 obj2)
{
// ...
}
}
Into something like this:
public class A
{
private List<IDependency2> _things;
A(IDependency1 obj1)
{
_things = new List<IDependency2>();
foreach (var x in someCollection)
_things.Add(NewInstanceOf<IDependency2>());
}
}
The key point is that in the first example obj2 is a singleton instance of IDependency2. In the second example an unpredictable number of instances of IDependency2 are created.
I have considered having a Func<IDependency2> parameter in the constructor, but I discussed this with an aquaintance who suggested I use IDependencyResolver because it would be more explicit.
In DI the interface acts as a contract about the dependencies.
as you say there will exist
an unpredictable number of instances of IDependency2
this screams for me for any kind of injected collection
example:
interface IDependency2List
{
IEnumerable<IDependency2> Items;
}
interface IDependency2
{
//bla
}
public class A
{
public A(IDependency1 dep1, IDependency2List dep2List)
{
}
}
You could add a factory interface like:
public interface IDependencyFactory<T> where T : class, new()
{
T Create();
}
And a simple implementation:
public class SimpleDependencyFactory<T> where T : class, new()
{
public T Create()
{
return new T();
}
}
Then your classes constructor would take the factory as a parameter:
public class A
{
private List<IDependency2> _things;
public A(IDependency1 obj1, IDependencyFactory<IDependency2> dep2Factory)
{
_things = new List<IDependency2>();
foreach (var x in someCollection)
_things.Add(dep2Factory.Create());
}
}
This will not compile because of someCollection though. Also obj1 is never used in your example. I don't know why you added it in the first place. Note that what's powerfull about factories is that you could add more complicated implementations that didn't simply create an object with a parameterless constructor. Look for different factory patterns. Popular ones are the Factory Method and Abstract Factory.