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.
Related
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");
}
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.
I would like know if there is a way to have a ManagerClass that calls the constructors of different classes that share the same interface and inherit form the same base class. I can not call the specific derived class constructors themselves because the user can choose which objects to create at runtime, hence I have no knowledge of which derived objects to create until runtime.
For example:
public class managerClass : ISomeInterface
{
public BaseClass apply(someDataType) //(Notice return type is BaseClass)
{
run constructors of the derivedClasses or create essentially new derived objects, pass someDataType into the constructors
}
}
public class derivedClass : BaseClass, ISomeInterface
{
public void doSmthg(){manipulate data and store}
}
public class derivedClass2 : BaseClass, ISomeInterface
{
public void doSmthg(){manipulate data in another way and store}
}
Currently managerClass does not inherit from same BaseClass however if this somehow helps to allow me to do what I wish to do I am not against making this change.
You might take a look at the Activator class:
Type type = typeof(derivedClass2);
ISomeInterface instance = (ISomeInterface)Activator.Create(type);
There are some more overloads, like passing a classname instead of a type.
More info: http://msdn.microsoft.com/en-us/library/system.activator.aspx
Else you should look at Factory Design Pattern here http://msdn.microsoft.com/en-us/library/ee817667.aspx
What is your problem? Sure you can say:
public BaseClass Apply(SomeDataType someDataType)
{
BaseClass instance;
if (/* your condition */)
{
var dc = new DerivedClass();
// do stuff to/with dc
instance = dc;
}
else
{
var dc2 = new DerivedClass2();
// do stuff to/with dc2
instance = dc2;
}
// do common stuff to/with instance
return instance;
}
If all you want developers to have to do is create the class and the your manager will automatically be able to create instances of it, use Reflection to gather a list of the options to present to the user, and use Activator to create the instance when requested.
Dictionary<string, Type> DerivedOfferings{get;set;}
... //somewhere in the setup of your manager.
foreach (Type t in AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IEmtRequestProcessor)))))
{
DerivedOfferings.Add(t.Name, t);
}
//provide list of options to users.
IList<string> GetOfferingOptions(){
return DerivedOfferings.Keys.ToList();
}
...
public BaseClass GetOffering(string name){
return (BaseClass)Activator.CreateInstance(DerivedOfferings[type]);
}
If there is some logic that needs to be performed to decide which derived offering to create, you can provide an attribute for the developers to decorate their classes with which would hold information to perform the logic against.
public sealed class CreatureAttribute:Attribute
{
public int NumberOfLegs{get;set;}
public Color HairColor{get;set;}
public int NumberOfWings{get;set;}
public bool BreathsFire{get;set;}
}
[CreatureAttribute(NumberOfLegs=6, HairColor = Color.Magenta, NumberOfWings=0, BreathsFire=True)]
public class PurpleDragon: ICreature
{
...
}
Then retrieve these during enumeration and store these with the options.
List<CreatureCriteria> CreatureOptions{get;set;}
EnumerateOptions()
{
foreach (Type t in AppDomain.CurrentDomain.GetAssemblies().SelectMany(a => a.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(ICreature)))))
{
foreach (CreatureAttribute creatureAttribute in
t.GetCustomAttributes(typeof (CreatureAttribute), false)
.Cast<CreatureAttribute>()
{
CreatureOptions.Add(
new CreatureCriteria{
Legs = creatureAttribute.NumberOfLegs,
HairColor = creatureAttribute.HairColor,
...
ConcreteType = t
}
);
}
}
}
And evaluate based on the criteria provided by the user..
ICreature CreateCreature(CreatureCriteria criteria){
CreatureCriteria bestMatch = CreatureOptions.FindBestMatch(criteria);
// perform logic comparing provided criteria against CreatureOptions to find best match.
return (ICreature)Activator.CreateInstance(bestMatch.ConcreteType);
}
This will be generics 101 for many but below is sample code so I can understand better.
public interface IRecordedItemsProcessor<T>
{
ObservableCollection<RecordedItem> Load(string name);
void Save();
RecordedItem Parse(T itemToParse);
}
public class FileLoadingProcessor : IRecordedItemsProcessor<string>
{
public ObservableCollection<RecordedItem> Load(string name)
{
}
public void Save()
{
}
public RecordedItem Parse(string itemToParse)
{
}
}
public class MyClass
{
public MyClass(IRecordedItemsProcessor<T> processor)
{
}
}
The issue is that MyClass needs a dependency on IRecordedItemsProcessor<T> but will not compile as it does not know what T is. How can this be resolved? Making MyClass implement a seems odd as all it needs to do is call Load/Save
Thanks
First solution is the most simple one: lift generic declaration to class level, like
public class MyClass<T>
{
public MyClass(IRecordedItemsProcessor<T> processor)
{
}
}
Then you could instantiate MyClass as following:
var myClass = new MyClass<string>(new FileLoadingProcessor());
Console.WriteLine (myClass);
Second solution is a removing generic input from constructor and inferring types. Then you don't need to specify generic exactly from call. Class declaration will look like:
public class MyClass
{
public void Process<T>(IRecordedItemsProcessor<T> processor)
{
}
}
And then you can call simply
var my = new MyClass();
my.Process(new FileLoadingProcessor());
The Idea is that you always need to specify class-level generics explicitly, but method level generics can be inferred by the compiler.
Third solutions is to encapsulate creation mechanisms inside MyClassFactory. This is quite flexible, but it might seem a little bit complicated, because descendants of IRecordedItemsProcessor<T> don't define generic at class level, so we should go to implemented interfaces and grab there generic types. And only then we can construct Generic MyClass. Listing is given below:
public class MyClassFactory
{
public MyClass<T> MakeMyClassFor<T>(IRecordedItemsProcessor<T> processor)
{
var processorGenericType = processor.GetType()
.GetInterfaces()
.Single(intr=>intr.Name == "IRecordedItemsProcessor`1")
.GetGenericArguments()[0];
var myClassType = typeof(MyClass<>).MakeGenericType(processorGenericType);
return Activator.CreateInstance(myClassType, processor) as MyClass<T>;
}
}
Now you can create MyClass very simply
var myClassFactory = new MyClassFactory();
var res = myClassFactory.MakeMyClassFor(new FileLoadingProcessor());
Console.WriteLine (res);
All of these three approaches have their pros and cons. Consider taking into account the context, in which you are going to use them.
You could do the following:
Create a new interface IRecordedItemsProcessor (non-generic)
Move Load and Save to this IRecordedItemsProcessor
Make IRecordedItemsProcessor<T> inherit from this IRecordedItemsProcessor
Make MyClass expect IRecordedItemsProcessor in its constructor
This makes it clear that MyClass doesn't care what type the processor might be able to parse, or even that it can parse things at all - it only knows that it can save and load.
You could inherit from a non-generic marker interface, this removes the need to know about T in your class:
public interface IRecordedItemsProcessor
{
}
public interface IRecordedItemsProcessor<T> : IRecordedItemsProcessor
{
ObservableCollection<RecordedItem> Load(string name);
void Save();
RecordedItem Parse(T itemToParse);
}
And then you can use any IRecordedItemsProcessor like:
public class MyClass
{
public MyClass(IRecordedItemsProcessor processor)
{
}
}
The generic type, as written, is being declared on the MyClass constructor which means the generic type must be defined at the MyClass level:
public class MyClass<T>
{
public MyClass(IRecordedItemsProcessor<T> processor)
{
}
}
However, if the generic type was declared at a method level, it would only have to be defined at the method level:
public class MyClass
{
public void MyMethod<T>( IRecordedItemsProcessor<T> processor )
{
}
}
EDIT
Based on your comment:
I want a class that can call the Load/Save methods but not be worried
that T is.
Then you'll need 2 interfaces: 1 for the load/save and then one with the parsing. In this case, you could use inheritance:
public interface IRecordedItems
{
ObservableCollection<RecordedItem> Load( string name );
void Save();
}
public interface IRecordedItemsProcessor<T> : IRecordedItems
{
RecordedItem Parse( T itemToParse );
}
public class MyClass : IRecordedItems
{
#region Implementation of IRecordedItems
public ObservableCollection<RecordedItem> Load( string name )
{
throw new NotImplementedException();
}
public void Save()
{
throw new NotImplementedException();
}
#endregion
}
EDIT 2
Based on your gist example, the type dependency could be moved off of the interface and directly into the interface method:
public class RecordedItem {}
public interface IRecordedItemsProcessor
{
ObservableCollection<RecordedItem> Load( string name );
void Save();
RecordedItem Parse<T>( T itemToParse );
}
public class MyClass
{
private readonly IRecordedItemsProcessor _processor;
public MyClass( IRecordedItemsProcessor processor )
{
_processor = processor;
processor.Parse<string>( "foo" );
processor.Parse<int>( 10 );
processor.Parse<RecordedItem>( new RecordedItem() );
}
}
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();