Create class object based on string identifier in C#
-
12-12-2019 - |
Question
I am new to programming to kindly bear me. I using c sharp, .net 4, VS 2010
I have a interface class called IHandler
with method IsValidate()
.
I have a message like AMOUNT 50 22.4
, where AMOUNT
is identifier.
So format of messages can be like FLOW 12 33 23.1
, again where FLOW
is identifier.
Now, based on the identifier i have different classes like ( I have around 15 - 20 classes like this, as i have to validate different message formats and sequence)
AmountValidator
FlowValidator
In these classes i have implementation of IsValidate()
method, as these implement IHandler
class.
Now my question is, once i identify the identifier of my message like AMOUNT
or FLOW
i want to create instance of the class.
What is the best way to do this?( I don't want to create 30 instances in, if else statement )
Appreciate any help.
Solution
You can do it like so:
IHandler handler = (IHandler)Activator.CreateInstance("assemblyname", "typename");
handler.IsValidate();
The assembly name can be found on the properties page on the project where the handlers are.
Here:
You also have to remember that everything is case-sensitive, so the typename argument can't be AMOUNTValidator if the class is actually named AmountValidator.
EDIT: Factory sample:
public static class HandlerFactory {
private static Object factoryLock = new Object();
private static List<IHandler> handlers = null;
public static IHandler Gethandler(String type) {
if (handlers == null) {
lock (factoryLock) {
if (handlers == null) {
IEnumerable<Type> types = typeof(HandlerFactory).Assembly.GetTypes().Where(t => t.GetInterfaces().Contains(typeof(IHandler)));
handlers = types.Select(t => (IHandler)Activator.CreateInstance(t));
}
}
}
return handlers.Where(h => h.Type == type);
}
}
public interface IHandler {
String Type { get; }
Boolean IsValid(String data);
}
OTHER TIPS
A factory implementation where you should list your validators once in the constructor, assuming the validators are stateless :
public class HandlerFactory
{
private Dictionary<string, IHandler> _handlers = new Dictionary<string,IHandler>();
public HandlerFactory()
{
_handlers.Add("AMOUNT", new AmountValidator());
_handlers.Add("FLOW", new FlowValidator());
}
public IHandler Create(string key)
{
IHandler result;
_handlers.TryGetValue(key, out result);
return result;
}
}
Let me know if you want me to elaborate with Reflection and IoC. That would change the way you initialize the dictionary.
If all your IHandler
classes are contained in the same assembly as your application (not dynamically loaded like plugins), Factory method pattern could be a good choice. You can centralizes the creation of IHandler
classes with this design pattern.
If, on the other hand, the IHandler
classes are loaded at runtime, you need to take advantage of .NET Reflection.
There are also open source IoC containers that can help with object creations, but I guess they are a bit of an overkill.