using System; using System.Collections.Generic; namespace Chernobyl.Creation { /// /// An that caches the results from another /// and returns the cache result if a request matches a /// cached item. /// public class CacheFactory : Builder, IFactory { /// The instance that creates keys for items /// that are to be cached or found. /// The instance used to create items if a cached /// item cannot be found and returned. public CacheFactory(Func keyCreator, IFactory factory) : this(keyCreator, factory, new Dictionary()) {} /// /// Initializes a new instance of the class. /// /// The instance that creates keys for items /// that are to be cached or found. /// The instance used to create items if a cached /// item cannot be found and returned. /// The instance where cached items are stored. public CacheFactory(Func keyCreator, IFactory factory, IDictionary cache) { keyCreator.ThrowIfNull("keyCreator"); _keyCreator = keyCreator; factory.ThrowIfNull("factory"); _factory = factory; cache.ThrowIfNull("cache"); _cache = cache; } /// public TResult Create(T1 arg1) { TKey key = _keyCreator(arg1); if (!_cache.TryGetValue(key, out var result)) { // We do not have this instance cached. Have the factory create a new instance and report it. result = _factory.Create(arg1); _cache[key] = result; } ReportCreation(new CreationEventArgs(result, arg1)); return result; } /// /// The instance that creates keys for items that are to be cached or /// found. /// readonly Func _keyCreator; /// /// The instance used to create items if a cached item cannot be found /// and returned. /// readonly IFactory _factory; /// /// The instance where cached items are stored. /// readonly IDictionary _cache; } }