WPF c# Subscribe/Publish events mechanism using reflection - right or wrong? - c#

I want to achieve a simple Subscribe/Publish mechanism within a WPF application so i can subscribe to events from different places in the application specifying the event type and handler method, and then when publishing the event, my mechanism will call all the subscribed methods on the subscribers. I cannot use the RoutedEvent as I want to raise events freely without being forced to the visual tree.
I am able to achieve the above using c# reflection. But as I am pretty new to c# and WPF(coming from Java), I want to be sure that this is the preferred way.
Is It ??
Many Thanks,

It looks like you want the "Event Aggregator" pattern from the Prism framework. Surely you can implement it by yourself, although I don't see why you might need reflection for it.

Related

Access build events without using DTE

When capturing build events you can simply listen to the DTE2.Events.BuildEvents event. However is it possible to listen to these events without the use of DTE. I have read and heard from several people and sources that you should generally avoid using DTE, if somehow possible, due to its bad implementation or whatever.
In general if you're trying to automate Visual Studio you can either use DTE, which is the standard automation approach, or use native interfaces. The native interfaces start 'IVs...', e.g. IVsSolution. In both cases the technology is ancient and poorly-documented. As you suggest, a native solution does tend to be better.
Having said that, for the tasks running on a build that I've needed I ended up using DTE, which can be easier to program and made to work reliably.
I've found the equally-ancient articles (not the tools!) on the mztools.com website to be quite useful on this stuff, as well as the MSDN docs of course. Add 'mztools' to your Google search. For example, what mztools says on build events (Google 'mztools build events') is useful even though it dates from 2013.
I just want to share the code which actually works and achieves exactly what I needed. This was possible through the help of #Rich N, thanks for that one. It is actually easier than I thought, it is always the same procedure
Get the Svs... class from the GetService method and cast it to the corresponding interface.
Than append the Event Handler Class with the Advise... method.
// First of get the IVsSolutionBuildManager via the SVsSolutionBuildManager with the GetService method
var service = GetService(typeof(SVsSolutionBuildManager)) as IVsSolutionBuildManager;
// Appending the Events
service.AdviseUpdateSolutionEvents(new Events(), out var cookie)
// The class which handles the Event callbacks
public class Events : IVsUpdateSolutionEvents
{
// The implemented methods from the interface
}

How to use SynchronizingObject for event calls

For an application that I'm working on I use SpotifyLocalAPI, and I want to use the events that the API has. But, as someone who is into C# for a couple of months now, I'm not sure where to start. There is another project based on this API that uses the events, but it's in WPF, and that makes it a different deal if I understand my googeling correctly. This means that for a WinForms I have to do things a bit differently, but I can't seem to figure out how.
The documentation of the API states that You can set a SynchronizingObject, then the events will be called on the specific context. When I look at how the WPF project did this, it has a function (found here) to do some magic, and poof, it works.
If I understand this answer correctly the SynchronizingObject is a property of the ISynchronizeInvoke interface, which "provides synchronous and asynchronous communication between objects about the occurrence of an event.".
Okay, so far so good. I think I understand the basic working of the interface, but how am I supposed to work with it? How do I convince the application that it should react to the event? How should I define the _spotify.SynchronizingObject? (Which is the main problem for me right now)
You can set the SynchronizationObject to be any UI element that implements IShynchronizeInvoke (Form, UserControl etc). Check out the example Winforms app here. Note that this is optional, and in that example app, they have chosen to use Invoke() explicitly in the event handlers. The important thing to remember is that if you want to update the UI, then the code to do so must be run on the UI thread. Some more details on this here.

Communication between different forms

In C#, using winforms, what is the best way to make forms talk to each other? Sending data, messages, strings, whatever, from on to the other?
Delegates?
Ideas?
We'ved used something called the Event Pattern successfully in several Winform applications. Here's a good link that will help you get started.
You can create events in one form and then register for those events in the other form. You can also simply access properties from one form to the other. For example maybe in the constructor of the second form, you would pass a variable for the first form.
It sounds like what you're looking for are events though. When some event happens any delegate that is registered will be called.
There is a tutorial on MSDN for events here.
all depends on what you want to communicate.
Let's say it is configuration data; You could create a static property on main form called Settings, which would expose your object. Than all forms would see that same Settings instance, and all would see any changes.
for extra credit you could implement INotifyPropertyChanged, and have it trigger an event. that way all forms looking at Settings would be notified if anything changed.

Dynamically overriding a method -or- observing when a method is called at runtime?

I'm primarily an Objective-C/Cocoa developer, but I'm trying to implement the Observer pattern in C#.NET, specifically mimicking the NSKeyValueObserving protocols and methodology.
I've gotten as far as mimicking NSKVO with manual support, as described in Apple's KVO Programming Guide (see http://tinyurl.com/nugolr). Since I'm writing the setValue:forKey: methods myself, I can implement auto KVO notification through there.
However, I'd like to somehow implement auto KVO on all properties by dynamically overriding them at runtime. For example, replacing Button.Title.set with:
set {
this.willChangeValueForKey("title");
title = value;
this.didChangeValueForKey("title");
}
So, this is my question:
How do I dynamically override a method or property at runtime in C#? I've gotten as far as getting and invoking methods and properties by name using Reflection.MethodInfo. Alternatively, can I observe the runtime and find out when a method is about to be/has been called?
Dynamic metaprogramming and aspect oriented programming are not yet strongly supported in C#. What you can do, is look at a free tool called PostSharp - it allows supports weaving aspects into your code around properties and method calls quite easily.
You can implement the INotifyPropertyChanged interface (without postsharp) and it can be used in certain contexts to notify observers that a value of a property has changed. However, it still requires that each property actually broadcast the change notification - which generally requires it to be specifically coded to support that. Injecting change notification to existing code (without actually changing the source) is not an easy thing to do in straight-up C#. PostSharp (other other AOP/dynamic proxy libraries) make this sort of thing dramatically easier.
I'm not sure if you need to go down this road or not. But if you want to implement overrides of a method (i.e. generating new code for the method?) then it is possible with Emit. I would explore any other suggestions first before diving into those deep waters.
You're looking for INotifyPropertyChanged. You can dynamically implement that using PostSharp, Castle DynamicProxy or probably any other proxying library.
This does not solves the problem of having to add the tracking code dynamically, but can be interesting to read: Trackable Properties with Weak Events
With this stuff you are able to track changes to specific properties and it makes easier to implement INotifyPropertyChanged (i.e. track changes to all properties).
After doing extensive research on this subject, it appears that I can't do exactly what I'd like to do with .NET in its current state.
PostSharp's method is done at compile time, meaning I can't dynamically insert my own implementations to methods.
Reflection.Emit allows me to do this dynamically, but it generates a new instance of the created subclass - I need to do this so it works with the original instance.
INotifyPropertyChanging and INotifyPropertyChanged would be perfect if any of the existing .NET classes actually used them.
... so, at the moment I'm a bit stuck. I've put a more detailed piece on what I'm doing and how I'm trying to achieve in a post on my blog. Here's hoping .NET 4.0's dynamic dispatch will help!

CompositeWPF: EventAggregator - when to use?

I've been looking in to the Composite Application Library, and it's great, but I'm having trouble deciding when to use the EventAggregator... or rather - when NOT to use it.
Looking at the StockTraderRI example, I'm even more confused. They are using the EventAggregator in some cases, and "classic" events in other cases (in for example the IAccountPositionService interface).
I've already decided to use it for communication with a heavy work task, that should run on a background thread. In this case the EventAggregator offers marshalling of threads behind the scenes, so I don't have to worry much about that. Besides that I like the decoupling this approach offers.
So my question is: When I've started using the EventAggregator in my application, why not use it for all custom events?
This is a good question. In Composite WPF (Prism) there are 3 possible ways to communicate between parts of your app. One way is to use Commanding, which is used only to pass UI-triggered actions down the road to the actual code implementing that action. Another way is to use Shared Services, where multiple parts hold a reference to the same Service (Singleton) and they handle various events on that service in the classical way. For disconnected and asynchronous communication, as you already stated, the best way is to use the Event Aggregator (which follows closely Martin Fowler's pattern).
Now, when to and not to use it:
Use it when you need to communicate between modules. (for example, a Task module needs to be notified when a Task is created by any other module).
Use it when you have multiple possible receivers or sources of the same event. For example, you have a list of objects and you want to refresh it whenever an object of that type is saved or created. Instead of holding references to all open edit/create screens, you just subscribe to this specific event.
Don't use it when you only have to subscribe to normal events in the Model View Presenter area. For example, if your presenter listens to changes in the Model (for example the Model implements INotifyPropertyChanged) and your Presenter needs to react on such changes, it's better that your Presenter handles directly the PropertyChanged event of the Model instead of diverting such events through the Event Aggregator. So, if both the sender and receiver are in the same unit, there's no need to "broadcast" such events to the whole application.
I hope this answers your question.

Categories