In simple words:
A Flyweight factory that for a given, already known, key will always give the same object as response. For new keys will create the instance and return it.
Using the factory:
ISomeFactory<string, object> factory = new FlyweightFactory<string, object>();
var result1 = factory.GetSomeItem("string 1");
var result2 = factory.GetSomeItem("string 2");
var result3 = factory.GetSomeItem("string 1");
//Objects from different keys
bool shouldBeFalse = result1.Equals(result2);
//Objects from same key
bool shouldBeTrue = result1.Equals(result3);
Implementation:
public interface ISomeFactory<TKey,TResult> where TResult : new()
{
TResult GetSomeItem(TKey key);
}
public class FlyweightFactory<TKey, TResult> : ISomeFactory<TKey, TResult> where TResult : new()
{
public TResult GetSomeItem(TKey key)
{
TResult result;
if(!Mapping.TryGetValue(key, out result))
{
result = new TResult();
Mapping.Add(key, result);
}
return result;
}
public Dictionary<TKey, TResult> Mapping { get; set; } = new Dictionary<TKey, TResult>();
}
Extra Notes
I would recommend to add to this solution the use of an IoC Container
(as explained in a different example here) instead of creating your own new instances. One can do it by adding a new registration for the TResult
to the container and then resolving from it (instead of the dictionary
in the example).