In the application I am developing I am facing a situation; I want to know if there is a design pattern for this. It's as follows
What is a good strategy to implement this? Right now what we are doing is -
In the code, get the algorithm type and use reflection to instantiate the appropriate algorithm type. In C# we use code similar to below
System.Reflection.Assembly types = System.Reflection.Assembly.LoadFile(System.Reflection.Assembly.GetExecutingAssembly().Location.ToString());
foreach (Type t in types)
if (t.Name==classname)
createinstanceof(t)
//classnames is the list of all the class types that is loaded from reference table in DB.
My gut feeling is there should be a simpler/better way to do this as it seems a very standard problem. I know the strategy pattern - but what I want is to simplify and possibly remove manual tasks.
You can use Interface + Reflection to avoid storing algorithm names in database.
Create an Interface IMySortingAlgorithms as,
public interface IMySortingAlgorithms
{
string Name { get; }
string[] Sort(string[] input);
}
Now, write a Factory that uses reflection to get the sorting algorithm.
public static class MyAlgoFactory
{
private static Dictionary<string, IMySortingAlgorithms> m_dict;
/// <summary>
/// For all the assmeblies in the current application domain,
/// Get me the object of all the Types that implement IMySortingAlgorithms
/// </summary>
static MyAlgoFactory()
{
var type = typeof(IMySortingAlgorithms);
m_dict = AppDomain.CurrentDomain.GetAssemblies().
SelectMany(s => s.GetTypes()).
Where(p => {return type.IsAssignableFrom(p) && p != type;}).
Select(t=> Activator.CreateInstance(t) as IMySortingAlgorithms).
ToDictionary(i=> i.Name);
}
public static IMySortingAlgorithms GetSortingAlgo(string name)
{
return m_dict[name];
}
}
All your sorting algorithms can now implement this interface.
public class MySortingAlgo1 : IMySortingAlgorithms
{
#region IMySortingAlgorithms Members
public string Name
{
get { return "MySortingAlgo1"; }
}
public string[] Sort(string[] input)
{
throw new NotImplementedException();
}
#endregion
}
This way you need not add the class names to database whenever you create a new class for sorting.
Following is the non-Linq version of MyAlgoFactory
/// <summary>
/// For all the assmeblies in the current application domain,
/// Get me the object of all the Types that implement IMySortingAlgorithms
/// </summary>
static MyAlgoFactory()
{
m_dict = new Dictionary<string, IMySortingAlgorithms>();
var type = typeof(IMySortingAlgorithms);
foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
{
foreach (Type p in asm.GetTypes())
{
if (type.IsAssignableFrom(p) && p != type)
{
IMySortingAlgorithms algo = Activator.CreateInstance(p)
as IMySortingAlgorithms;
m_dict[algo.Name] = algo;
}
}
}
}