//http://www.codedomain,
// with inspiration of http://codingcraftsman.wordpress.com/2012/04/30/espirit-descalier/
using System;
using System.Collections.Generic;
namespace StrategySelector {
public enum InstanceType {
Singelton,
Instance
}
public class StrategySelector<K, T> {
private readonly Dictionary<K, StrategyStorage> _lookup = new Dictionary<K, StrategyStorage>();
public bool RegisterStrategy<TStrategyType>(K value, InstanceType instanceType) where TStrategyType : T, new() {
if (_lookup.ContainsKey(value)) {
return false;
}
if (instanceType == InstanceType.Singelton) {
_lookup[value] = new StrategyStorage {
InstanceMode = instanceType,
Singleton = new Lazy<T>(() => new TStrategyType())
};
} else {
_lookup[value] = new StrategyStorage {
InstanceMode = instanceType,
StrategyType = typeof (TStrategyType)
};
}
return true;
}
public T SelectStrategy(K value) {
if (!_lookup.ContainsKey(value)) {
throw new Exception("Strategy not available");
}
if (_lookup[value].InstanceMode == InstanceType.Instance) {
return (T) Activator.CreateInstance(_lookup[value].StrategyType);
}
return _lookup[value].Singleton.Value;
}
class StrategyStorage {
internal InstanceType InstanceMode { get; set; }
internal Lazy<T> Singleton { get; set; }
internal Type StrategyType { get; set; }
}
}
}
// Sample usage
using System;
using StrategySelector;
namespace ConsoleStrategy {
internal interface IStrategy {
void DoSomething();
}
internal class MyStrategy1 : IStrategy {
public void DoSomething() {
Console.WriteLine("Strategy1");
}
}
internal class MyStrategy2 : IStrategy {
public void DoSomething() {
Console.WriteLine("Strategy2");
}
}
internal class Program {
public enum Strategies {
Strategy1,
Strategy2
};
private static void Main(string[] args) {
var strategySelector = new StrategySelector<Strategies,IStrategy>();
strategySelector.RegisterStrategy<MyStrategy1>(Strategies.Strategy1,InstanceType.Instance);
strategySelector.RegisterStrategy<MyStrategy2>(Strategies.Strategy2,InstanceType.Singelton);
strategySelector.SelectStrategy(Strategies.Strategy1).DoSomething();
strategySelector.SelectStrategy(Strategies.Strategy2).DoSomething();
strategySelector.SelectStrategy(Strategies.Strategy1).DoSomething();
strategySelector.SelectStrategy(Strategies.Strategy2).DoSomething();
System.Console.ReadLine();
}
}
}