I am building an WinForms application with a UI that only consists of a NotifyIcon and its dynamically populated ContextMenuStrip. There is a MainForm to hold the application together, but that is never visible.
I set out to build this as SOLIDly as possible (using Autofac to handle the object graph) and am quite pleased with my success, mostly getting along pretty well even with the O part. With the extension I am currently implementing it seems I have discovered a flaw in my design and need to remodel a bit; I think know the way I need to go but am a bit unclear as to how to exactly define the dependencies.
As mentioned above, the menu is in part populated dynamically after starting the application. For this purpose, I defined an IToolStripPopulator interface:
public interface IToolStripPopulator
{
System.Windows.Forms.ToolStrip PopulateToolStrip(System.Windows.Forms.ToolStrip toolstrip, EventHandler itemclick);
}
An implementation of this is injected into the MainForm, and the Load() method calls PopulateToolStrip() with the ContextMenuStrip and a handler defined in the form. The populator's dependencies are only related to obtaining the data to use for the menu items.
This abstraction has worked nicely through a few evolutionary steps but isn't sufficient anymore when I need more than one event handler, e.g. because I am creating several different groups of menu items - still hidden behind a single IToolStripPopulator interface because the form shouldn't be concerned with that at all.
As I said, I think I know what the general structure should be like - I renamed the IToolStripPopulator interface to something more specific* and created a new one whose PopulateToolStrip() method does not take an EventHandler parameter, which is instead injected into the object (also allowing for much more flexibility regarding the number of handlers required by an implementation etc.). This way my "foremost" IToolStripPopulator can very easily be an adapter for any number of specific ones.
Now what I am unclear on is the way I should resolve the EventHandler dependencies. I think the handlers should all be defined in the MainForm, because that has all the other dependencies needed to properly react to the menu events, and it also "owns" the menu. That would mean my dependencies for IToolStripPopulator objects eventually injected into the MainForm would need to take dependencies on the MainForm object itself using Lazy<T>.
My first thought was defining an IClickHandlerSource interface:
public interface IClickHandlerSource
{
EventHandler GetClickHandler();
}
This was implemented by my MainForm, and my specific IToolStripPopulator implementation took a dependency on Lazy<IClickHandlerSource>. While this works, it is inflexible. I would either have to define separate interfaces for a potentially growing number of handlers (severely violating OCP with the MainForm class) or continuously extend IClickHandlerSource (primarily violating ISP).
Directly taking dependencies on the event handlers looks like a nice idea on the consumers' side, but individually wiring up the constructors via properties of lazy instance (or the like) seems pretty messy - if possible at all.
My best bet currently seems to be this:
public interface IEventHandlerSource
{
EventHandler Get(EventHandlerType type);
}
The interface would still be implemented by MainForm and injected as a lazy singleton, and EventHandlerType would be a custom enum with the different types I need. This would still not be very OCP compliant, but reasonably flexible. EventHandlerType would obviously have a change for each new type of event handler, as would the resolution logic in MainForm, in addition to the new event handler itself and the (probably) newly written additional implementation of IToolStripPopulator.
Or.... a separate implementation of IEventHandlerSource that (as the only object) takes a dependency on Lazy<MainForm> and resolves the EventHandlerType options to the specific handlers defined in MainForm?
I'm trying to think of a way of actually getting the event handlers out of MainForm in a feasible way, but can't quite seem to right now.
What is my best option here, providing the loosest coupling and most elegant resolution of the different event handlers?
[*Yes, I probably should have left the name alone to really comply with OCP, but it looked better that way.]
What is my best option here, providing the loosest coupling and most
elegant resolution of the different event handlers?
Common solution are not exist and it depends on the global application architecture.
If you want a loosest coupling, EventAggregator pattern can help you in such case (your IEventHandlerSource similar to that):
Pattern Description - http://martinfowler.com/eaaDev/EventAggregator.html
Implementation in Prism - http://msdn.microsoft.com/en-us/library/ff921122.aspx
But, global events should be used with great caution - they can smudge architecture, because subscribe to the event will be possible anywhere.
Important thing in DI and IoC: lower dependency should not to know about higher dependency.
I think, and as Leon said earlier, will be better to create some interface like ITool<T> and store list of tools in the MainForm. After some action MainForm will invoke certain methods in this tools.
Firstly, I think you shouldn't claim your mainform must contain all event handlers. You clearly ran into the fact that there are different handlers with different needs (and probably different dependencies), so why should they all be fitted into the same class?
You can probably take some inspiration from the way events are handled in other languages. WPF uses Commands, Java has Listeners. Both are objects, not just a delegate, making them easier to deal with in an IOC scenario. It's fairly easy to simulate something like that. You could abuse the tag on your toolbar items, like this: Binding to commands in WinForms or use lambda expressions inside PopulateToolbar (see Is there anything wrong with using lambda for winforms event?) to associate the toolbar item with the correct command. That's assuming that since PopulateToolbar knows which items need to be created it also know which action/command belongs to each item.
The object representing the action can have their own dependencies injected, independently of the main form or other actions. Toolbar items with their own actions can then be added or removed later without affecting your main form or any of the other actions, each action can independently be tested and refactored.
Bottom line, stop thinking about EventHandlers, start thinking about Actions/Commands as an entity in their own right and it will become easier to come up with a suitable pattern. Make sure you understand the Command Pattern, because that's pretty much what you need here.
Have you tried to use an event aggregator? See: Caliburn framework, event Aggregator
An event aggregator will decouple the toolstrip from you main form.
public interface IToolStripPopulator
{
ToolStrip PopulateToolStrip(ToolStrip toolstrip);
}
Wrap the aggregator for convenience like this:
public static class Event
{
private static readonly IEventAggregator aggregator = new EventAggregator();
public static IEventAggregator Aggregator
{
get
{
return aggregator;
}
}
}
You define one or more event classes, for example:
public class EventToolStripClick {
public object Sender {get;set;}
public EventArgs Args {get;set;}
}
In the controller that creates the toolstrip, publish the custom event in the Click handler write:
public void ControllerToolStripClick(object sender, EventArgs args )
{
Event.Aggregator.Publish(new EventToolStripClick(){Sender=sender,Args=args)});
}
In the mainForm implement the interface IHandle
public class MainForm : Form, IHandle<EventToolStripClick>
{
...
public void Handle(EventToolStripClick evt)
{
//your implementation here
}
}
If you are hosting child components within your form, and they can populate the main application "shell".
You could have a base class ShellComponent, that inherits from System.Windows.Forms.ContainerControl. This will give you a design surface as well. Instead of relying IToolStripPopulator, you could have ITool like such.
public inteface ITool<T>
{
int ToolIndex { get; }
string Category { get; }
Action OnClick(T eventArgs);
}
In ShellComponent you could call, public List<ITool> OnAddTools(ToolStrip toolStrip) from the MainForm each time a view is loaded. This way the component would be responsible for populating the toolstrip.
The 'ShellComponent' would then ask the IoC container for handlers that implement ITool<T>. This way your ITool<T> provides a way to separate the event (in the MainForm, or the ContainerControl) and push this out to any class. It also allows you to define exactly what you want to pass through for arguments (as opposed to MouseClickEventArgs ect).
Related
What is the difference between using MessagingCenter and standard .NET event handlers for informing interested parties of changes?
Two (untested) implementations of the same thing are below to demonstrate:
public class FooClass {
public event EventHandler SomeEvent;
public void DoSomeWork() {
// ... stuff
if(SomeEvent != null)
SomeEvent(this, EventArgs.Empty);
}
}
public class BarClass {
FooClass _foo;
public BarClass() {
_foo = new FooClass();
_foo.SomeEvent += delegate {
// ... did something
};
}
}
Verses:
public class FooClass {
public const string SomeEventName = "SomeEvent";
public void DoSomeWork() {
// ... stuff
MessagingCenter.Send<FooClass>(this, SomeEventName);
}
}
public class BarClass : IDisposable {
public BarClass() {
MessagingCenter.Subscribe<FooClass>(this, FooClass.SomeEventName, delegate {
// .. did something
});
}
public void Dispose() {
MessagingCenter.Unsubscribe<FooClass>(this, FooClass.SomeEventName);
}
}
From what I can tell there doesn't seem to be any difference, but if anyone can suggest any pros or cons for either, that'd help me understand. Currently, I've been using event handlers.
Is there any point in switching to using MessagingCenter? Or any new best practice?
The MessagingCenter from Xamarin is used to reduce coupling between ViewModels, as the sender and receiver do not need to know each other.
You can still build a similar structure by creating something like an "EventHub"/"EventAggregator" which knows sender and receiver and uses .NET events.
The MessagingCenter itself is kind of an EventAggregator
ImageSource : https://msdn.microsoft.com/en-us/library/ff921122.aspx
Here is a nice explanation of EventAggregators.
An Event Aggregator is a simple element of indirection. In its
simplest form you have it register with all the source objects you are
interested in, and have all target objects register with the Event
Aggregator. The Event Aggregator responds to any event from a source
object by propagating that event to the target objects.
To Answer the question:
Is there any point in switching to using MessagingCenter? Or any new
best practice?
If you are not using something like an EventAggregator it is a good choice to switch to the MessagingCenter, or build an EventAggregator on your own.
As Saruman made a good hint on explaining what coupling is. You allways want to reduce coupling for a clean code.
MessagingCenter is basically used in the Model-View-ViewModel
pattern.
It is a great way to communicate and pass data or notify about
updates among ViewModels without knowing who sent it to whom via a simple Message Contract.
Ex. In one screen if you make any service call to fetch the new data
and you want to notify other screens to update their UI via
broadcasting message from your current screen, then MessagingCenter
is the best approach.
It decouples them without making any dependency among ViewModels,
while EventHandlers makes dependency and may prohibit something
from being released. You explicitly have to decouple event handlers
from the events to better release the resources.
MessagingCenter should be applied when the receiver doesn't care
who sent the message and the sender doesn't care who will receive it.
Events should be used when the receiver needs to know who sent the
message, but the sender still doesn't care who handles it.
It is good to use MessagingCenter over Events but, if you make too much use of
too many Messages using MessagingCenter, it would be hard to
identify who sent it and when sent it, the relation between messages
would be hard to guess, thus making it hard time while debugging the
app.
If you have access to those classes (i.e from where you want to call your methods) then there really is not a lot of difference.
However if you don't have access to those classes(i.e inside a view model or decoupled class) then message subscription event aggregation is a useful tool
Message center reduces coupling and enables view models and other
components to communicate with without having to know anything about
each other besides a simple Message contract.
Coupling
In software engineering, coupling is the degree of interdependence
between software modules; a measure of how closely connected two
routines or modules are the strength of the relationships between
modules.
I found articles about and solutions to this question pertaining to Prism, but I didn't find anything pertaining to Caliburn Micro. I checked all questions here tagged with Caliburn.Micro and EventAggregator, but didn't find anything Caliburn specific about this seemingly basic issue.
Scenario: I want to publish events to the EventAggregator that don't have any information, other than signaling that something happened.
Problem: First, in Caliburn Micro, the EventAggregator's Publish() method requires an instance of a type to be sent. Second, subscribing and handling events require the implementation of the IHandle<T> interface, where T is the type of instances that we want to receive. It seems that this is fully designed around publishing and handling actual data.
Goal: To be able to publish simple events without having to create and instantiate multiple empty/dummy classes, and without having to Handle() unnecessary events that I need to filter further with conditionals.
My solution so far
This is what I want to improve/replace. (Obviously, this solution is problematic because it creates tighter coupling around the concrete classes, but in my use case this is not a big issue, since it's a small project with singular publishing components for a given event, and the EventAggregator serves other practical goals.)
I made a generic Signal<T> class that implements the singleton pattern, providing a static instance of itself through the Instance property:
public class Signal<T>
{
public static readonly Signal<T> Instance = new Signal<T>();
private Signal() { }
}
So I can publish events in the following way (SignalSourceClass is an example):
_eventAggregator.PublishOnUIThread(Signal<SignalSourceClass>.Instance);
And handle events by declaring the implementation of IHandle<T> in the following way:
IHandle<Signal<SignalSourceClass>>
This way I can send and receive "empty" events by creating only this single Signal class. (Of course this is a limited solution, since components can only send one event this way.)
I suspect that this solution is primitive (well, let's just call it a fact), and that there is something better that I'm overlooking.
Just create a enum with all possible signals you want:
public enum ProjectSignals
{
Connected,
Disconnected,
Openned
}
then just
_eventAggregator.PublishOnUIThread( ProjectSignals.Connected );
and
class SomeClass : IHandle<ProjectSignals>
{
public void Handle( ProjectSignals signal )
{
switch (signal)
{
case Connected:
break;
}
}
}
as for my understanding, part of writing (unit-)testable code, a constructor should not do real work in constructor and only assigning fields. This worked pretty well so far. But I came across with a problem and I'm not sure what is the best way to solve it. See the code sample below.
class SomeClass
{
private IClassWithEvent classWithEvent;
public SomeClass(IClassWithEvent classWithEvent)
{
this.classWithEvent = classWithEvent;
// (1) attach event handler in ctor.
this.classWithEvent.Event += OnEvent;
}
public void ActivateEventHandling()
{
// (2) attach event handler in method
this.classWithEvent.Event += OnEvent;
}
private void OnEvent(object sender, EventArgs args)
{
}
}
For me option (1) sounds fine, but it the constructor should only assign fields. Option (2) feels a bit "too much".
Any help is appreciated.
A unit test would test SomeClass at most. Therefore you would typically mock classWithEvent. Using some kind of injection for classWithEvent in ctor is fine.
Just as Thomas Weller said wiring is field assignment.
Option 2 is actually bad IMHO. As if you omit a call to ActivateEventHandling you end up with a improperly initialized class and need to transport knowledge of the requirement to call ActivateEventHandling in comments or somehow else, which make the class harder to use and probably results in a class-usage that was not even tested by you, as you have called ActivateEventHandling and tested it but an uninformed user omitting the activation didn't, and you have certainly not tested your class when ActivateEventHandling was not called, right? :)
Edit: There may be alternative approaches here which are worth mentioning it
Depending on the paradigm it may be wise to avoid wiring events in the class at all. I need to relativize my comment on Stephen Byrne's answer.
Wiring can be regarded as context knowledge. The single responsibility principle says a class should do only one task. Furthermore a class can be used more versatile if it does not have a dependency to something else. A very loosely coupled system would provide many classes witch have events and handlers and do not know other classes.
The environment is then responsible for wiring all the classes together to connect events properly with handlers.
The environment would create the context in which the classes interact with each-other in a meaningful way.
A class in this case does therefore not know to whom it will be bound and it actually does not care. If it requires a value, it asks for it, whom it asks should be unknown to it. In that case there wouldn't even be an interface injected into the ctor to avoid a dependency. This concept is similar to neurons in a brain as they also emit messages to the environment and expect answer not knowing neighbouring neurons.
However I regard a dependency to an interface, if it is injected by some means of a dependency injection container just another paradigm and not less wrong.
The non trivial task of the environment to wire up all classes on start may lead to runtime errors (which are mitigated by a very good test coverage of functional and integration tests, which may be a hard task for large projects) and it gets very annoying if you need to wire dozens of classes and probably hundreds of events on startup manually.
While I agree that wiring in an environment and not in the class itself can be nice, it is not practical for large scale code.
Ralf Westphal (one of the founders of the clean code developer initiative (sorry german only)) has written a software that performs the wiring automatically in a concept called "event based components" (not necessarily coined by himself). It uses naming conventions and signature matching with reflection to bind events and handlers together.
Wiring events is field assignment (because delegates are nothing but simple reference variables that point to methods).
So option(1) is fine.
The point of constructor is not to "assign fields". It is to establish invariants of your object, i. e. something that never changes during its lifetime.
So if in other methods of class you depend on being always subscribed to some object, you'd better do it in the constructor.
On the other hand, if subscriptions come and go (probably not the case here), you can move this code to another method.
The single responsibility principle dictates that that wiring should be avoided. Your class should not care how, or where from it receives data. It would make sense to rename OnEvent method to something more meaningful, and make it public.
Then some other class (bootstrapper, configurator, whatever) should be responsible for the wiring. Your class should only be responsible for what happens when a new data come's in.
Pseudo code:
public interface IEventProvider //your IClassWithEvent
{
Event MyEvent...
}
public class EventResponder : IEventResponder
{
public void OnEvent(object sender, EventArgs args){...}
}
public class Boostrapper
{
public void WireEvent(IEventProvider eventProvider, IEventResponder eventResponder)
{
eventProvider>event += eventResponder.OnEvent;
}
}
Note, the above is pseudo code, and it's only for the purpose to describe the idea.
How your bootstrapper actually is implemented depends on many things. It can be your "main" method, or your global.asax, or whatever you have in place to actually configure and prepare your application.
The idea is, that whatever is responsible to prepare the application to run, should compose it, not the classes themselves, as they should be as single purpose as possible, and should not care too much about how and where they are used.
When implementing DI, both Mark Seemann, and Misko Hevery say that constructors should be simple, and should only receive dependencies. They should not do anything else. (here and here)
However, often I would like to subscribe to events of the passed in dependencies, but if I do this in the constructor, then the constructor does more than receiving its dependencies, and if I don't, then the object is not fully initialized.
Would it be correct, then, to instantiate those objects which need to subscribe to events in the composition root, hook up their events, and then inject those instantiated objects?
For example:
// Composition root
Panel panel = new Panel();
Button button = new Button();
panel.OnButtonClick += button.Click;
Register<Panel>().AsSingle(panel);
Register<Button>().AsSingle(button);
// Panel Class
private Button _button;
public Panel(Button button)
{
_button = button;
}
void OnButtonClick()
{
// handle button click
}
as opposed to:
//composition root
Register<Panel>().AsSingle(panel);
Register<Button>().AsSingle(button);
// Panel Class
private Button _button;
public Panel(Button button)
{
_button = button;
OnButtonClick += button.Click
}
void OnButtonClick()
{
// handle button click
}
Yes, wiring up the events in the composition root would be the correct approach here.
This answer is primarily opinion based.
I usually does not use DI to presentation layer, because I assume the best use of DI is to make a persistence ignorance classes in domain (business) layer. The use of DI though, is to aim for stateless service class. It process requests regardless any specified state and is event-less, thus eliminate the need of events inside the service class.
What you want to create maybe is a control class, and not service class, therefore, assigning event is a real problem here. However, I don't think wiring an event violates the constructor rules thing, because it is just assinging event.
Why is it eventless?
It accept request, and process it. If you need something to do like: afterProcess, beforeProcess, etc, you can define the specific event in classes, and passing the interfaces as dependency.
What if I need to do event based?
Sometimes you need an event to be passed in some cases. You can do parameter injection using Func (or adapter in java) instead hooking it in the constructor.
I realize there is much discussion about singletons and why that are bad. That is not what this question is about. I understand the drawbacks to singletons.
I have a scenario where using a singleton is easy and appears to make sense. However, I want an alternative that will accomplish what I need without a lot of overhead.
Our application is designed as a client that typically runs on laptops in the field and communicates with a back end server. We have a status bar at the bottom of the main application. It contains a few text areas that show various statues and information as well as several icons. The icons change their image to indicate their state. Such as a GPS icon that indicates if it is connected or not as well as error state.
Our main class is called MobileMain. It owns the status bar area and is responsible for creating it. We then have a StatusBarManager class. The StatusBarManager is currently a static class, but could also be a singleton. Here is the start of the class.
public static class StatusBarManager
{
static ScreenStatusBar StatusBar;
/// <summary>
/// Creates the status bar that it manages and returns it.
/// </summary>
public static ScreenStatusBar CreateStatusBar()
{
StatusBar = new ScreenStatusBar();
return StatusBar;
}
The MobileMain asks the StatusBarManager for a StatusBar. It then uses the StatusBar. No other classes see the StatusBar, just the StatusBarManager.
Updates to the status bar can come from pretty much anywhere in the application. There are around 20 classes that can update the text areas on the status bar and additional classes that update the icon states.
There will only every be one StatusBar and one StatusBarManager.
Any suggestions for a better implemention?
Some thoughts that I had:
Make the StatusBarManager an instance class. In my MobileMain class hold onto a static public instance of the StatusBarManager class. Then to do status bar updates you would call MobileMain.StatusBarManager.SetInformationText or some other method of the manager. The StatusBarManager would not be a singleton, but the MobileMain would only be creating a static instance of it. The issue here is that MobileMain now has a StatusBar and a StatusBarManager, which just manages the StatusBar it owns. Still also have a globally avaialble static instance to the StatusBarManager, just a different owner.
Another idea was to use something like an EventEggregator class. I've never used one, but have read about them. I guess the concept is that it would be a globally available class. In each class that wants to update the status bar it would publish a StatusBarUpdate event. The StatusBarManager would be the only classes subscribing to the StatusBarUpdate event, and receive all of the notifications. I've read though that can end up with leaks with this approach if you are not carefull with unsubscribing from events when cleaning up objects. Is this approach worth looking into?
I prefere Static classes that hold your objects. So the amount of objects you can access is restircted by the interface your static class offers. Static is not bad as long as your application still scales.
Another good alternative to singletons is the Monostate pattern, where you have a class that implements private static fields to represent "singleton" behavior.
See:
Monostate
Monostate vs. Singleton
UPDATE:
It often helps me to keep a REST like api in mind, even for internal program structures. Having one class that is updated from everywhere and sends notices to everybody is hard to control in respect to raise conditions and infinity loops (Update -> Event -> Update -> ...)
Build an (static or not) Status bar interface that you can access where you need it. Through a Static class where you get access to your Status bar interface or by dependency injection if you use such techniques (not recommended for smaller projects). Every call to your status bar interface has to be independent from any events that might be raised by the Status bar to avoid further issues with raise conditions. Think of the status bar interface like a website that can be called from other parts of the program to push and pull information.
Having a StatusBar class or a StatusBarManager class or not is not a big deal. But having many classes in your app know about StatusBars and StatusBarManagers is a bad idea, it will cause strong coupling, and some day probably pain.
How?
Imagine that the components that currently report status to a status bar have to be reused in another app that
- uses a text console to report status?
- reports status to multiple places?
or
- doesn't report status at all!
Best alternative:
-Event listening. Expose a Status Changed event on your class (you can use a callback), or perhaps on an existing shared resource that your classes have in common. Other parties, like your status bar, can subscribe to the event. And should unsubscribe whenever the subscription is no longer needed/valid, to prevent leaks, as you mention!
-Since you've tagged WPF, for WPF, having a dependency property 'StatusText', might seem like another tempting option, with this approach when you have multiple status properties, you need a way of figuring out which one is telling you the most interesting status that needs to be displayed on your status bar now! Which could be a binding, multibinding (blech, complexity), or dependency property changed event handler.
However - I would advise you to keep DependencyObjects and DependencyProperties limited to your UI layer as much as possible. The reason is that they rely implicitly on a Dispatcher on the UI thread, and so can't be adapted easily for non-UI chores.
Since there are many different parts of your app you may also possibly find it's reasonable to have a combination of both of these, using some one place and some another.
You could simply use the Observer pattern and add the StatusBar as a listener to your 20 objects. This will eliminate the singletons and better follow SRP and DIP, but you will have to consider whether it is worth the effort. A singleton may be better if the indirection adds too much complexity and dependency injection is not possible.
public class StatusBar implements StatusListener {
}
public interface StatusListener {
public statusChanged(String newStatus)
}
Classes will depend implicitly on any use singleton and explicitly to any parameters in the constructor. I would suggest adding an interface to the singleton, so just the methods needed would be exposed to the classes using the IStatusBar. This is more code, but will ease unit testing.
It's hard to give advice without knowing more of your application's architecture, but perhaps you should consider dependency injection. For example, pass a StatusBar instance to the constructor of each class that directly uses it.