The Design Pattern of Wrapping Exist Event in My Own Class - c#

all:
This issue comes from my currently working C# project. In solution, it includes three projects, one is UI project, another is interface project, the third is component project. The basic idea of my solution is UI project can dynamic load the component DLL which inherit interface defined in interface project. And in interface project, I defined two classes, one is a interface which is used by UI project to dynamic load DLL, and this interface defines all exposure entities in component object. And besides this interface, there's another abstract component core class which inherit public interface, and it includes all common operations in actual component object. I draw a plot following to describe my explanation before.
"UI Class ---> Interface <--- Abstract Component Core <--- Actual Component"
And in my design, I use C# BackgroundWorker in abstract component core object. And BackgroundWorker contains two event ProgressChanged and RunWorkerCompleted. In my design idea, these two events should be registered by UI Class. For example, UI class can register its operation when component's BackgroundWorker's progress changing or operation finishing. And another thing is that I don't want to expose BackgroundWorker object in Component Core to UI class, so the BackgroundWorker object is defined in abstract component core, not in interface. So in my raw design, I create two events in interface which accepts same event handler as BackgroundWorker's two events. As following:
event EventHandler<ProgressChangedEventArgs> ProcessChanged;
event EventHandler<RunWorkerCompletedEventArgs> RunWorkerCompleted;
And in later some places, I will assign these two event handlers to BackgroundWorker's actual events. Code as following:
mBackgroundWorker.ProgressChanged += new ProgressChangedEventHandler ( this.ProcessChanged );
mBackgroundWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler ( this.RunWorkerCompleted );
But I don't like this design. Because the user of componet (here is UI class) assign its event handler to component's event, and it real operation, component will add (+=) this event handler to BackgroundWorker's event handler. So this cause BackgroundWorker will have several same event handler if UI running again and again. The idea situation for me is that: 1-BackgroundWorker's event only can contain one event handler; 2-When user assign event handler to component core's own event, then it can transfer this event handler to BackgroundWorker's event at the same time;
Anyone can give me some workable design idea? Thanks!

I find a solution to solve my problem. I can use add and remove keyword to customer define my event accessor in my component core class. Code as following:
public virtual event ProgressChangedEventHandler ProcessChanged
{
add
{
lock ( mEventLock ) { mBackgroundWorker.ProgressChanged += value; }
}
remove
{
lock ( mEventLock ) { mBackgroundWorker.ProgressChanged -= value;}
}
}
So this can solve my problem. User assigning to component core event can immediately assign the event to BackgroundWorker's related event. This is what I want. So in my above question, two parts of code can integrate into one part of code.

Related

Dependency injection of events

Could somebody describe how should looks like class Worker with two events which triggers after some action is happened.
I have class Worker with one method ExecuteAsync. Inside this method I'm executing method i.e. DoStuff(). After that I want execute events. Event one and event two has different logic and have independent arguments which should be passed.
What goals I want to achieve.
I want to mock those events and test Worker without side effects.
Class Worker and events is SRP classes.
I can easily inject another realization of events without breaking my code.
I'm not completely understand this thing:
How should look's like realisation with injecting "body" of events.
Could I execute one event but inject inside it file search logic and sending http logic?
public class Worker
{
public event EventHandler<FileFoundArgs> FileFound;
public event EventHandler<SendHttpArgs> SendHttp;
public async Task ExecuteAsync()
{
DoStuff();
FileFound?.Invoke(this, new FileFoundArgs(file));
SendHttp?.Invoke(this, new SendHttpArgs(file));
}
}

How to implement Prism EventAggregator event queue on subscribers

I have an application architecture like this:
When UDP servers inside the UDP service receive different types of messages it publishes Prism events to managers. Those UDP servers have their own threads so when the events published they sometimes cause multithreading issues inside the managers.
To prevent that I want to create an event handler and queue inside the subscribing managers. When subscriber receives an event, its only job is to try to Enqueue the event payload to ConcurrentQueue inside the managers and return (I think this is called store and forward). Then I will have a worker that will read this queue and send the event parameters to related methods.
Every manager will have its own event queue, event handler and worker.
My "event queue":
But when I try to implement this I couldn't get past some issues:
1- When you subscribe to an event, public class TestEvent1 : PubSubEvent<Class1>, like this, GetEvent<TestEvent1>().Subscribe(OnTestEvent1), callback method(OnTestEvent1) must have same type of parameters of the event, in this case Class1, OnTestEvent1(Class1 class1). I need a type to store every received data and event type.
How can I use the same callback method for all my events inside the subscriber manager that have different types?
Example:
// Events
public class TestEvent1 : PubSubEvent<Class1>
{
}
public class TestEvent2 : PubSubEvent<Class2>
{
}
public class TestEvent3 : PubSubEvent<List<Class3>>
{
}
// Subscriptions
_eventAggregator.GetEvent<TestEvent1>().Subscribe(EventHandler, true);
_eventAggregator.GetEvent<TestEvent2>().Subscribe(EventHandler, true);
_eventAggregator.GetEvent<TestEvent3>().Subscribe(EventHandler, true);
// Callback
private void EventHandler("What's inside here?")
{
_eventQueue.Enqueue(payload);
return;
}
2- Since I want to store all of the received events for a manager inside a single queue, the same type problem applies to this too, what should be my T when creating ConcurrentQueue?
3- Is this viable? Are there any other approaches, patterns(I found mediator but I didn't research it deeply enough) that I can use like this?
What I tried:
1- I tried to use object or dynamic type but then I will lose compile-time security.
2- I thought of creating an interface and implementing it on all of my custom classes so I can use it for general type but what to do about events with built-in types?
PS: I had another question about this but I felt like I didn't explain myself clearly so I tried my best again.
How can I use the same callback method for all my events inside the subscriber manager that have different types?
You don't. The event aggregator isn't designed that way. The type of the event is used to distinguish subscriptions and to distribute the event to the subscribers that actually want it, so you can only ever subscribe to an individual event type.
As said before, you shouldn't be using the event aggregator here at all, because there are much better tools for what you're trying to achieve.
Since I want to store all of the received events for a manager inside a single queue
If, for example, the manager was an dataflow ActionBlock it would come with a fully functional queue preinstalled.

Where should events be raised?

I'm not new to C#, but events is one of the most confusing topics I confront in the language.
one of the questions is: where should I assign the event handler to the event, or the question in other form: why most events are raised in the subscriber constructor? what does it mean?
like this example (taken from the book Mastering Visual C# )
public ReactorMonitor(Reactor myReactor)
{
myReactor.OnMeltdown +=
new Reactor.MeltdownHandler(DisplayMessage);
}
Raise = generate. Events are not raised in the subscriber constructor. The subscriber does not raise events at all. The event source raises/generates events, and subscribers subscribe to, receive, and handle them.
Events in c# are nothing more than function pointers, i.e. a variable that contains a pointer (or list of pointers) to a function that matches a specific signature (typically Action<object,EventArgs>). Or in the words of this MSDN article:
Delegates are like C++ function pointers but are type safe.
When you subscribe to an event, you are essentially saying "Store the address of my function. When X happens, please call it (along with any other function whose address is stored)."
Thus the code
myReactor.OnMeltdown += Meldownhandler;
can be read as
objectThatRaisesEvents.FunctionPointer = MyHandler;
Notice that MyHandler is not followed by parentheses. If it were MyHandler() that means you are invoking the function, the value of the expression MyHandler() is actually the return value of the function; MyHandler by itself doesn't invoke the function or return its value but instead returns the address of the handler itself. So the above line of code takes the address of MyHandler and stores it in a variable named FunctionPointer.
When the object that raises events invokes FunctionPointer() it is telling c# to obtain the address of the function stored in FunctionPointer and invoke it.
So it is really calling MyHandler() indirectly. Thus these two lines do exactly the same thing:
objectThatRaisesEvents.FunctionPointer();
MyHandler();
Also notice the += in your example. In c# that is the equivalent of
objectThatRaisesEvents.FunctionPointer =
objectThatRaisesEvents.FunctionPointer + MyHandler;
We typically use that syntax because there might be several handlers that subscribe to an event. += has the effect of appending our handler to the list. You could use = instead, but it would unsubscribe any existing handlers.
To answer your question-- when should you subscribe to events? That is a very broad question, but typically
In an ASP.NET web page, you'd subscribe during the Init event.
In a Windows Form, you'd subscribe in the InitializeComponent method.
There are many other contexts of course... the bottom line is you should subscribe before you need to receive notifications of occurrences of the event.
The event is one of the standard features of .NET Framework built using delegate model implementing the Observer design pattern.
https://msdn.microsoft.com/en-us/library/edzehd2t(v=vs.110).aspx
https://en.m.wikipedia.org/wiki/Observer_pattern
Where you subscribe to the event depends on the business rules, but most of the time you want to subscribe at the earliest possible moment which is usually the constructor of the class interested in the handling of the event.
When events should be raised on the other hand depends on what you are trying to communicate to the subscribers if it is a notification of the state change then you raise an event as soon as state is changed.
An event is a message sent by an object to signal the occurrence of an
action. The action could be caused by user interaction, such as a
button click, or it could be raised by some other program logic, such
as changing a property’s value.

C# thread communication using events

I want to achieve something life below -
My application will start UI Module, from UI module I will initiate core module. Core module will keep on running on different thread. On specific action in core module, I want to raise and event which will be subscribed by UI module.
Basically, I want to send specific enum information to UI module.
Please suggest me a model for it. I am trying to achieve it.
Will both module run with any blocking in this model?
Thanks in advance
You can use the Progress class with the IProgress interface to do exactly this.
In your UI context create a Progress object with a generic argument of whatever data you need to pass.
Subscribe to it's event to do whatever you want to do when the background task updates you.
Have the background task accept an object of type IProgress (which Progress implements) and have it periodically Report with the relevant data.
The ProgressChanged event will be fired whenever Report is called, and the Progress object will capture the current synchronization context of where it was created, which is a fancy way of saying that the event will be fired in the UI thread.
I would recommend using the BackgroundWorker Class
Checkout this tutorial
http://www.dotnetperls.com/backgroundworker
Class reference
http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx
Here how it goes in simple ways:
Open your UI form (design view)
Add a backgroundworker control on your UI form
Open the properties pane and switch to events (lightning bolt icon)
Double click on dowork and runworkercompleted events (this will generate event handlers)
Go to the event handlers (in code)
Now write your processing code in dowork handler and add the result you want to send to your ui module like so e.Result = your_enum (or any other Object);
Next come to the runworkercompleted handler and typecast the RunWorkerCompletedEventArgs e (RunWorkerCompletedEventArgs object) to your enum (or object you returned from the dowork handler) and use it in UI as needed.
Finally do not forget to initiate the backgroundworker : backgroundWorker1.RunWorkerAsync() from your UI mdoule
Remark: If you need to report progress periodically use the ReportProgress method of BackgroundWorker class. There are two overloads for this method:
1) http://msdn.microsoft.com/en-us/library/ka89zff4.aspx
2) http://msdn.microsoft.com/en-us/library/a3zbdb1t.aspx
The first one allows to report only the progress percentage and the second one you can use to pass in any object also if you will
This should be pretty easy to do with either the System.Threading.Thread or BackgroundWorker or Task class. You can use either of those to run code on another thread.
When you need to notify the UI, just raise an event. To build events, take a look here:
How can I make my own event in C#?
Then you just need to make sure to call Invoke to make sure that you execute the final UI update code on the correct thread. For that, take a look at this:
Thread Control.Invoke
Sounds like a classic use of the Mediator pattern to me. The Mediator allows disconnected components to talk to each other.
I just happen to have a copy of this in my own MVVM framework, which you can grab from here :
http://cinch.codeplex.com/SourceControl/changeset/view/70832#796984
Also grab this
http://cinch.codeplex.com/SourceControl/changeset/view/70832#797008
My implementation allows you to do it using WeakReference so no strong references are held. Its also allows subscribers to hook up methods to listen to certain events using attributes, and publishers to broadcast a new messaage of T.
Publisher/Subscriber simply register with Mediator
//done by both subscriber and publisher
Mediator.Instance.Register(this);
//Subscriber
[MediatorMessageSinkAttribute("DoBackgroundCheck")]
void OnBackgroundCheck(string someValue) { ... }
//publisher might typically do this
mediator.NotifyColleagues("DoBackgroundCheck", "Nice message");
You may need to use your own SynchronizationContext when subscriber gets message (WPF / Winforms have pre built ones of these) to dispatch call to correct thread.
I also allow for synchronise/aysynchronise calls

Bubbling up events to be subscribed to

I have a class ChatManager, which has a ChatServer and a ChatClient(WCF) class inside of them.
I want my controller which instantiates the ChatManager to be able to subscribe to the UserConnected, UserDisconnected and MessageReceived events that are on the ChatClient.
What is the most elegant and logical way to do this? Is it silly for me to define the events in the ChatClient like I have, and then redefine the events in the ChatManager solely to pass the events up to the Controller without it having to deal with or know about the ChatClient? The ChatManager would subscribe to the events of the ChatClient, and then fire off its own events which the ChatController would be listening to.
I know WPF has the concept of bubbling up of events, but I don't know if that is for this type of scenario, since nothing is part of a user interface.
I'd start by questioning whether both ChatManager and ChatController can both justify their own existence. Generally whenever you find yourself creating a "Manager" class, it really isn't necessary, especially if part of what it is doing consists of merely relaying messages.
Controller classes can struggle against SRP since their "responsibility" is quite broad. In cases where you want to delegate responsibility for certain behaviour then leave the responsibility for the ChatClient with the controller, and initialize a subordinate controller with the ChatClient (through a contract interface) so that it can interact with the client as needed. Just make sure that when you start registering for events that you de-register those events before discarding subordinates or the client, otherwise you'll be looking at managed memory leaks.
It is not bubbling events you are looking for. You can easily subscribe to these events by calling an instance of the child class in your parent (ChatManager) and subscribing to the Events like so :
chatManager.UserConnected += (param1, param2) => {
//your code here
};
Unless you have a need for an event to only conditionally reach the things that would subscribe to it (or to be processed sequentially by multiple handlers), "bubbling" isn't really something you should need. Using an event aggregator would probably be the best way to go.

Categories

Resources