Hi,
today I thought about how to decouple parts of my application. With decoupling I at first thought about a manager which dynamically loads modules and then uses their output to feed a following module... not quite flexible if you more or less "pipe" one part after another and then just chain their results (like in a LINUX-bash command call e.g.: "ps -aux | grep vi" where a manager calls first ps and then grep).
A better approach is to let a global instance store the data when it appears and then push it dependent of the use case to the module which needs it (application #1 lists its errors -> manager pushes it to the log manager -> write to log). This brought me to a big question: Do I need a coordinator if the software parts can talk between each other?
As usual the answer is "it depends". A manager or coordinator is e.g.: OK if you have a main system like notepad++ and you want to load add-on functionality to use another output formatter. Let the modules talk between each other if e.g.: you separate the business logic in independent parts (divide and conquer), but on the same level (not as master-slave).
For my application the communication of the software parts seems to look good. Now I asked myself how to communicate inside of an application (and still as a condition: decoupled). Middleware is over sized for a single application. Message queues or messaging in general seems over sized too. Eventbus was over sized in the first place too, but here google came in the game. I google-d different kinds of event buses and found awesome solutions. Open source and commercial. Big libraries and light-weight solutions. Then I found a very inspiring post of trystan ( http://trystans.blogspot.co.at/2012/01/simplest-eventbus.html / http://trystans.blogspot.co.at/2012/01/simplest-typesafe-eventbus.html ).
I decided to use an own event bus. The following code shows the basic idea (an event bus based on the version of trystan's blog). I decided to build the event bus system more like the .Net's event system using EventHandler and EventArgs and call an event by name.
My code follows below... it is still a basic solution, but it worked for me.
kind regards,
Daniel
BusEventArgs.cs
EventBus.cs
Tester.cs
today I thought about how to decouple parts of my application. With decoupling I at first thought about a manager which dynamically loads modules and then uses their output to feed a following module... not quite flexible if you more or less "pipe" one part after another and then just chain their results (like in a LINUX-bash command call e.g.: "ps -aux | grep vi" where a manager calls first ps and then grep).
A better approach is to let a global instance store the data when it appears and then push it dependent of the use case to the module which needs it (application #1 lists its errors -> manager pushes it to the log manager -> write to log). This brought me to a big question: Do I need a coordinator if the software parts can talk between each other?
As usual the answer is "it depends". A manager or coordinator is e.g.: OK if you have a main system like notepad++ and you want to load add-on functionality to use another output formatter. Let the modules talk between each other if e.g.: you separate the business logic in independent parts (divide and conquer), but on the same level (not as master-slave).
For my application the communication of the software parts seems to look good. Now I asked myself how to communicate inside of an application (and still as a condition: decoupled). Middleware is over sized for a single application. Message queues or messaging in general seems over sized too. Eventbus was over sized in the first place too, but here google came in the game. I google-d different kinds of event buses and found awesome solutions. Open source and commercial. Big libraries and light-weight solutions. Then I found a very inspiring post of trystan ( http://trystans.blogspot.co.at/2012/01/simplest-eventbus.html / http://trystans.blogspot.co.at/2012/01/simplest-typesafe-eventbus.html ).
I decided to use an own event bus. The following code shows the basic idea (an event bus based on the version of trystan's blog). I decided to build the event bus system more like the .Net's event system using EventHandler and EventArgs and call an event by name.
My code follows below... it is still a basic solution, but it worked for me.
kind regards,
Daniel
BusEventArgs.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EventBus { public class BusEventArgs : EventArgs { public BusEventArgs(object value = null) { Value = value; } public object Value { get; private set; } public static BusEventArgs Empty = new BusEventArgs(); } } |
EventBus.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EventBus { public static class EventBus { private static Dictionary<string, List<EventHandler<BusEventArgs>>> handlers = new Dictionary<string, List<EventHandler<BusEventArgs>>>(); public static void Publish(string eventName, BusEventArgs e) { Publish(null, eventName, e); } public static void Publish(object sender, string eventName, BusEventArgs e) { foreach (EventHandler<BusEventArgs> handler in handlers[eventName]) { handler(sender, e); } } public static void Subscribe(string eventName, EventHandler<BusEventArgs> handler) { if (!handlers.ContainsKey(eventName)) { handlers.Add(eventName, new List<EventHandler<BusEventArgs>>()); } handlers[eventName].Add(handler); } } } |
Tester.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading; using System.Threading.Tasks; namespace EventBus { class Program { public static object locker = new object(); public static bool IsStoped; static void Main(string[] args) { Thread raiser = new Thread(() => Raise()); Thread listener = new Thread(() => Listen()); raiser.Start(); listener.Start(); Console.ReadLine(); } private static object Listen() { IsStoped = false; EventBus.Subscribe("onRaise", (sender, e) => WriteRaised()); while (!IsStoped) { Thread.Sleep(100); } Console.WriteLine("finished"); return null; } private static object WriteRaised() { Console.WriteLine("raised"); IsStoped = true; return null; } private static object Raise() { Thread.Sleep(5000); EventBus.Publish(new object(), "onRaise", new BusEventArgs()); return null; } } } |
No comments:
Post a Comment