c# - Centralizing actions of a program -
i have program needs perform actions various forms. want keep actions in centralized space. each action has own class derived interface.
each action instantiated once, used on various places, contextmenu, ribbon, toolbar , on.
i have following code working, , want rid of typeof in when making list. want have strong typing, no reflection , possibility refactor.
can done more efficient?
class program { static void main(string[] args) { actionmanager actionmanager = new actionmanager(); list<someinterface> lista = actionmanager.createlist(typeof(do_a), typeof(do_b)); list<someinterface> listb = actionmanager.createlist(typeof(do_a), typeof(do_b)); } } public class actionmanager { private dictionary<type, someinterface> instantiatedactions = new dictionary<type, someinterface>(); public list<someinterface> createlist(params type[] actions) { list<someinterface> thelist = new list<someinterface>(); foreach (type type in actions) { if(!instantiatedactions.containskey(type)) { instantiatedactions.add(type, (someinterface)activator.createinstance(type)); } thelist.add(instantiatedactions[type]); } return thelist; } } public interface someinterface { } public class do_a : someinterface { } public class do_b : someinterface { } public class do_c : someinterface { }
you can create expressions return type if type has not been seen. allow keep strong typing , enforce someinterface implementations allowed passed in.
static void main(string[] args) { actionmanager actionmanager = new actionmanager(); list<someinterface> lista = actionmanager.createlist<someinterface>( () => new do_a(), () => new do_b()); list<someinterface> listb = actionmanager.createlist<someinterface>( () => new do_a(), () => new do_b()); } public class actionmanager { private dictionary<type, someinterface> instantiatedactions = new dictionary<type, someinterface>(); public list<someinterface> createlist<t>(params expression<func<t>>[] actions) { list<someinterface> thelist = new list<someinterface>(); foreach (var action in actions) { var type = getobjecttype<t>(action); if(!instantiatedactions.containskey(type)) { instantiatedactions.add(type, (someinterface)action.compile().invoke()); } thelist.add(instantiatedactions[type]); } return thelist; } private static type getobjecttype<t>(expression<func<t>> expr) { if ((expr.body.nodetype == expressiontype.convert) || (expr.body.nodetype == expressiontype.convertchecked)) { var unary = expr.body unaryexpression; if (unary != null) return unary.operand.type; } return expr.body.type; } }
the caveat needing both compile expression invoke , needing return type expression tree. however, per comment, ensure lazy instantiation if type has not been seen, guaranteeing type safety.
Comments
Post a Comment