How do I design View logic into c# projects - c#

I have three c# projects in my solution. One is a console app that simply calls into a class library project. The class library project does all the processing for the application. Then there is a WinForm project that displays a form and then when a button is pressed, calls the same logic in the class library project. As a result, there are two ways to run the logic, via the Console or via a Windows UI (WinForm).
My problem is that part way through the class library logic, if the UI app is being used, I want a custom WinForm form to appear to ask the user a question.
In the Console app, I want the same place in the logic to simply write out to the Console. In my understanding of architecture, you don't want the class library project to contain WinForm logic and require it to have references to all the WinForm references. But how do I make a call to the WinForms project (or something else) to display the custom WinForm form? There would be a circular reference where the class library would reference the main WinForm app and the WinForm app would reference the class library project.
What is the standard way of doing this?

You could create an interface that your library defines to communicate back to the caller, then have both your calling apps define their own implementaions of this interface, the library calls the methods on this interface and knows nothing of the implmentation.
The caller processes the methods accordingly...
public interface IProgressReporter
{
void ReportMessage(string message);
}
public class WinFormsProgressReporter : IProgressReporter
{
public void ReportMessage(string message)
{
MessageBox.SHow(message);
}
}
public class ConsoleAppProgressReporter : IProgressReporter
{
public void ReportMessage(string message)
{
Console.WriteLine(message);
}
}
public class LibraryClass
{
public static void SomeMethod(IProgressReporter rep)
{
rep.ReportMessage("Wooooohooooo!");
}
}

Why not define an inteface, IOutputHandler, that has a method called DisplayOutput. You would have 2 implementations of it, one for your winforms app and one for the console. You'd call the correct version of it at runtime. You could modify your class library to have a private field instance for the IOutputHandler, and then plug in the proper one at runtime.

You could raise an event in the class library that is listened to/registered from whatever your UI/Console layer is. That way it can decide to act on the event if it is deemed necessary in as many places as you desire. It really depends on how your architecture is setup.

This is where you need clear definition between your logic layer and your UI layer. It's perfectly acceptable and normal to put this sort of logic in your UI, since that bit can't reasonably live within the logic layer, as it is UI dependent.

Your logic should never, ever refer to any kind of UI component. If it does, it's wrong, and you need to redesign it to remove UI dependencies completely.

While the interface answers are probably better solutions, if it's just one method you could just use a delegate to pass the Console or WinForm method to the class library.

Another solution
In your class lib..
public void MyLibMethod(Action<string> callBack)
{
callBack("Yeh baby...");
}
Then call
Class.MyLibMethod(s=> Console.WriteLine(s));

Related

How to create a DLL library with a standard form layout to use on several forms?

I searched a lot of places but with no answer. I want to create a standard window form with a predefined layout on it like: borderless window, a panel with some code to be able to move the window around, close and minimize buttons, etc.
I imagine that this need to be an DLL so any other project that I create on the future could import and use this DLL. Even if I update the layout on DLL all my projects that use it automatically change instead of I having to manually change all windows forms on every project.
If someone could please explain to me step-by-step on how to do this, create, import and use the DLL, I would be very thankfull.
Edit: Sorry, it's WinForm. I want to be able to use this standard WinForm layout outside my solution, on other projects. The main solution will only have the standard WinForm layout I created, nothing else. The other projects should be able to insert their components, like buttons, panels, inside the standard WinForm layout. I think I might need to use NuGet package instead of DLL.
There are a lot of ways to do what you need. But first of all you need to do some analysis and design. Find out what layouts and controls are needed, what will change and in what ways. Identify possible modes or patterns to implement by the form. Some drawings on paper will help. Start with a single project to keep things very simple, and when you got it working, go on with a DLL or NuGet package. I'll try to explain a very quick and dirty example with a lot of assumptions.
In short, we will create a form that implements three behaviors or modes. Each mode is composed of two factors:
GUI. Controls are added, hidden, changed or moved around its
containers as needed.
Code. Event handlers, private methods and all the code to implement what the mode should do.
Every mode should have a single method performing all the needed changes in GUI and code.
An Enumeration should be created (at namespace level) with all needed mode names.
public enum EditFormMode { Default, CreateClient, EditClient }
The form Constructor should receive one argument of the enumeration type. And a switch will dispatch execution to the method.
{
public FormEditConfig(EditFormMode mode)
{
InitializeComponent();
switch (mode)
{
case EditFormMode.Default:
CreateDefaultMode();
break;
case EditFormMode.CreateClient:
CreateClientMode();
break;
case EditFormMode.EditClient:
CreateEditClientMode();
break;
}
}
private void CreateDefaultMode()
{ // do default stuff }
private void CreateClientMode()
{ // do create client stuff }
private void CreateEditClientMode()
{ // do edit client stuff }
}
And the code to create a form:
private FormEditConfig _theForm ;
_theForm = new FormEditConfig(EditFormMode.CreateClient);
That's the basic mechanism. How to retrieve data from the form to the calling code is very dependent on the concrete implementation.
Once all modes are implemented and tested, go on and create a new project for a class library, move files, add project references, build the solution and test again.

C# - Determining responsibility between GUI and logic class

I have a form and a logic class. Based on user actions, the class generates a list of actions. These actions then need to be displayed as buttons on the form, so the user can select from them.
My initial solution was this:
public class Logic {
public List<string> GetActions() {
List<string> result = new List<string>();
// ...prepare list
return result;
}
}
public class FrmGUI : Form {
Logic logic = new Logic();
private void PopulateButtons() {
foreach(string action in logic.GetActions(){
//...create button
}
}
}
The GUI retrieves the list of strings from the Logic class and then uses that to populate a panel with buttons. Now supposedly this is bad OO practise because I'm exposing something about how Logic class behaves. There is an assumption here that the GetActions method will always exist and that the Logic class will always be able to return this list of strings.
Another solution is this:
public class Logic {
public void PopulateButtons(Panel panel, Action<object, EventArgs> eventHandler) {
// ...prepare list
// ...populate buttons
}
}
public class FrmGUI : Form {
Logic logic = new Logic();
private void PopulateButtons() {
logic.PopulateButtons(this.panel1, actionButtonClickHandler);
}
}
Now here the GUI class knows nothing about the logic class and only expects to get the buttons populated. On the other hand, the logic class is now involved in GUI stuff.
What is the correct way to handle such cases. Or is there a third implementation which is better.
I'd use the former patttern: The Logic-layer creates information, and UI-layer uses that information to create the UI.
That way, if you decide to re-skin the UI to use a drop-down list of items you only have to change the UI layer, not the logic.
It means that the UI layer has a minimal dependency on the types/data provided by the logic layer (as long as it doesn't know anything about how the logic is implemented, that is fine), but the logic layer has no idea whatsoever about what the UI implementation is - which is what you want (the lower level components in a system should not know anything about the higher level design, while the higher level components must necessarily have a basic understanding of the low-level components that they utilise).
It would be preferable that the application (or some other external entity) creates both the Logic and UI and links them together, rather than the UI itself creating the Logic - this will help the UI and logic to be much more loosely coupled.
I would recommend placing a layer of abstraction between your Logic and your FrmGUI.
For a simplistic example, let's say you have a login in you application. Define an interface for your logical screen. Note there is no mention here of what controls are used. The Logic classes never knows the UI class/form used.
interface ILoginScreen : IScreen
{
event EventHandler LoginInvoked;
event EventHandler CancelInvoked;
string User { get; set; }
string Password { get; set; }
}
In your LoginLogic class you have code like this:
void Start() // initial LoginLogic method
{
ILoginScreen loginScreen = uiFactory.CreateLoginScreen();
loginScreen.User = string.empty;
loginScreen.Password = string.empty;
loginScreen.LoginInvoked += new EventHandler(LoginScreen_LoginInvoked);
loginScreen.CancelInvoked += new EventHandler(LoginScreen_CancelInvoked);
loginScreen.Show();
}
void LoginScreen_LoginInvoked(s, e)
{
if (ValidateCredentials(loginScreen.User, loginScreen.Password))
{
// goto the next screen logic controller
}
}
In your form, you implement ILoginScreen and refresh the UI fields with data from teh USer and Password properties. Additionally, you raise the required Login and Cancel events based on the user feedback (button click, Escape keystroke, whatever).
While this is a simplistic example, I do a lot of Windows Mobile and Windows CE apps where it is very common to want to run the same application on vastly different form-factors OS variants and this approach lets you literally snap on new GUI form-factors. The heart of that usage is the UIFactory that is dynamically loaded to provide the appropriate UI implementation.
That Logic can report the actions it supports (1st pattern) looks fine to me (but the return type of GetActions really should be IEnumerable<string> instead of a list).
Not so good is that in your sample the form instantiates the Logic class directly. Typically, you'd create an interface or abstract base class for the different types of Logic classes that you might have, and have concrete implementations fill in the functionality. The form would then get the logic to use through some inversion-of-control mechanism.
correct????? Over the years lots of people have invested lots of time in trying standardise this approach and I'm afraid the answer may be deduced from the number of ui design patterns out there!
You may want to look at MVC, MVP, MVVM patterns, all of which are in vogue at the moment.
In general:
it is a good idea to try to split logic from presentation, so you're on the right lines. But remember that one of the consequences of this split is that it is better for your "logic" not to know anything about presentation (since you already have a class responsible for that).
So you might want to think about the concept of "buttons", and think (from your logic point of view), "don't I really mean commands?". They only really become buttons when you think of them in the context of a screen. But, say, a command to load the transactions on a particular bank account....you don't need a screen to conceptualise how this would work.
A good thing I find is to imagine that you're going to develop this app with both a forms front end and, say, a web front end which does exactly the same thing. Obviously these two apps would have a totally different presentation layer because of the fundamentally different technologies involved.
But because you don't want to write code twice you'll have a "logic" layer too, where you'll stuff as much common code as you can. For example, deciding whether a bank account is overdrawn - doesn't matter whether you're web or win, overdrawn is still overdrawn. And conversely, any place where you'd end up writing different code between web and win belongs into your "presentation" layer. For example, displaying an overdrawn balance in red.
Food for thought.
the first one is better, because your interface between GUI and logic is just a list of string.
After, it all depends on the way you're calling actions on your logic class from your button.
If you have a generic method taking the action string, it's fine. If you need to call different methods on your logic class depending on the action string, you'll need a mapping in the GUI class to map action string and method call. you could also import this "action string - mapping method" from your logic class to keep things separated.
My opinion is, it depends on the reason for creating something like a logic tier and a GUI tier. I think the most common reason is to reuse the logic, e.g. to use it for a WPF and a web GUI, or the data has to be processed before sending it to the GUI. Your first example fits the mentioned pattern. In your second example the logic seems not to be reuseable, because its gui specific.
However, in the real world there it right or wrong answer. The architecture should fit your needs and make your project maintainable(e.g. by reduce redundant code).
In your case the question is: How often do you need these functions and where/when do you need them?

IoC: Wiring up dependencies on event handlers

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).

I want a design alternative to a singleton

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.

C# Trigger a method after another method (defined in a third party dll) is completed

This may fall into the category of method extending, overriding or polymorphism (I'm new to C# and OO so forgive me, I'm still learning :-) ).
I have an app that is utilizing a 3rd party API. Within the API there is a method for right click+select action on a custom control (the control is an image viewer where a user can right click and cycle to another image that exists within the parent group).
In my limited understanding I would think one of these 2 things would need to happen (whether either one can be done or whether either one is a good solution is up in the air!)
I don't want to override the existing method, I just want to append to it somehow.
If there was a way I could detect when the specific event was triggered and completed, then call my method. Set up some kind of listener if thats available.
Thanks!!
As you didn't post any reference, I'll try to outline some ways.
if there is an event
CustomControl cc = yourCustomControl;
cc.SelectionCompleted += (sender, args) => { YourMethod() };
This is using an anomynous event handler using a lambda.
Another way would be:
public class Form1 : Form
{
public Form1()
{
this.cc.SelectionCompleted += HandlerSelectionCompleted;
}
public void HandlerSelectionCompleted(object sender, EventArgs e)
{
YourCustomMethod();
}
}
there is a method to override
public class YourCustomControl : CustomControl
{
public override void Selection()
{
base.Selection(); // first call the original method
// now do some custom stuff
}
}
You can not override that method: that's right, if it's not protected/virtual/abstract whatever, or if you can not derive from that component's class.
You can search the component for the events and guess (if there is no any documentation) which event is fired after your desired action. And actually execute the code in that event handle.
There could be other "hacking" tricks, but I personally would avoid to do something like that, if not for personal passion, but focus on reachitecturing my program, in order to fit the requirements and support that component, as much as I can.
Regards.
What you are describing is a tenant of Aspect Oriented Programming AOP. If you want to instrument a 3rd party .NET dll, I would recommend PostSharp http://www.sharpcrafters.com/solutions/logging

Categories

Resources