c# - Passing delegates as parameters for mediator/subscriber pattern -
i'm looking appropriate , elegant way create mediator/subscriber architecture typed callbacks.
let's suppose have class 'events' i.e. delegates:
public class e { public delegate void somethinghappened (float a, int b); public delegate void progressfinished (int[] c); }
now want create mediator class register callbacks delegates , dispatch callbacks supplied parameters:
public class mediator { public static void register ( ???, action callback) { // supplied delegate += callback } public static void dispatch ( ???, params object[] list) { // executing supplied delegate params: delegate(list) } }
so use following way:
// class a: mediator.register (e.somethinghappened, onsomethinghappened); private void onsomethinghappened (float a, int b) { //.......... } // class b: mediator.dispatch (e.somethinghappened, 0.1f, 'qwe');
now problem can't pass delegate parameter register or dispatch. how solve problem?
you should take different approach: let senders dispatch messages, , have mediator dispatch them different handlers based on type.
using generics, refactored to:
// handlers should differentiated message type public class somethinghappenedmessage { public float { get; set; } public int b { get; set; } } public class mediator { private readonly dictionary<type, object> _dict = new dictionary<type, object>(); public void register<tmessage>(action<tmessage> callback) { _dict[typeof(tmessage)] = callback; } public void dispatch<tmessage>(tmessage msg) { var handler = _dict[typeof(tmessage)] action<tmessage>; handler(msg); } }
or, might have multiple handlers each message type:
public class mediator { readonly dictionary<type, list<object>> _handlersbytype = new dictionary<type, list<object>>(); public void register<tmessage>(action<tmessage> callback) { list<object> handlers; if (!_handlersbytype.trygetvalue(typeof(tmessage), out handlers)) _handlersbytype[typeof(tmessage)] = handlers = new list<object>(); handlers.add(callback); } public void dispatch<tmessage>(tmessage msg) { list<object> handlers; if (!_handlersbytype.trygetvalue(typeof(tmessage), out handlers)) return; foreach (action<tmessage> handler in handlers) handler(msg); } }
Comments
Post a Comment