I've come into an issue that must be quite common, but with little insight around the world of Google.
You see, my project has 3 parts that I use:
CommunicationClass.cs (Asynchronous Socket Class)
Form1.Designer.cs (Containing the objects of Form1)
Form1.cs (Main constructor and contains event handlers for objects)
Pretty basic setup.
However, I don't know where I put my communication class instance. The communication class sends/receives messages. So, my instance of ComClass in Form1 would use its void Send() in the event handler for the enter key being pressed (while in a textBox).
That works fine. What doesn't work fine is when the ComClass RECEIVES a message. It can't use the non-static voids of PrintMessage() in Form1.cs, and PrintMessage can't be a static void because richTextBox1, where the messages are shown, is non-static.
I'm wondering if another component of C# will help me access these and overcome my problem, but I'm too new to C# to know. I want to keep using the layout I have rather than switch to one like an example TCP chat client, where the form is created outside of Program.cs.
In C#, the standard paradigm for stuff like this is to use events. This ties in with the idea of the Observer Pattern in software design.
You are already using that for handling the key-press. The "trick" is to implement an event on your CommClass that the Form instance can subscribe to, in order to receive notification of incoming data.
The usual .NET Forms implementation is usually a kind of "poor man's MVC", in which the Form class winds up acting as controller and view all at the same time. Of course, doing so negates the main benefit of an MVC design, which is that the view is completely independent of the controller.
But you could (after learning more about the MVC design pattern) create a third "controller" class that ties together the view (your Form) and the model (your CommClass where the actual meat of the work is implemented).
If you want to go really cheesy, you could just pass your Form instance directly to the CommClass and have some special method that the CommClass knows to call when it receives data. But that's just doubling-down on the failure to separate concerns between your class, tying them even more closely. Maybe okay for a quick-and-dirty proof of concept, but that's no way to write code that you have any interest in reusing some time in the future.
Related
My question is about .NET 4.6.2, Winforms and C#. Let's assume we have complex system that uses several MDI WinForm instances with very complex UI structures (user controls, dock panels, tabcontrol,etc...). The request is to prepare some minimally invasive mechanism that will extend this application with layout customization feature. The user should be able to move/resize windows content and save it. I have already implemented this customization but I need to make it loaded and saved automatically without modyfying hundreds of OnLoad() and Dispose() methods. I can imagine it as follows:
All underlying customizable components must implement ILayoutSupport interface.
public interface ILayoutSupport
{
public void RestoreLayout()
public void SaveLayout();
}
public class MyUserControl: UserControl,ILayoutSupport {...}
Additionally, there is a deamon service LayoutController that listens all ILayoutSupport instance creations and it:
calls RestoreLayout each time new the instace is being created
calls SaveLayout when the instance is supposed to be diposed.
My questions are, is this approach "architecturarly" valid?
I tried to use CreateHandle event handler in my LayoutController service, but maybe there is better way to hook all specific types creations/disposings? I've considered to use C# attributes instead of interfaces and inject some routines into my windows, but I don't know how exactly it shoud go.
Or maybe there is better solution for my problem?
Thanks for all comments.
I'm developing a multi tenant n-tier web application using asp.net Mvc 5.
In my service layer I am defining custom events for every important action and raising these events once these actions are executed. For example
Public event EventHandler EntityCreated;
Public void Create(Entity item) {
Save(item);
......
EntityCreated(this, item);
}
I intend on hooking up business rules and notifications to these events. The main reason I want to use events is decoupling of the logic and easy plug-ability of more events handlers without modifying my service layer.
Question:
Does it make sense using events and delegates in asp.net?
Most examples I find online are for win forms or wpf. I get the advantage when it comes to multithreaded applications. Also the events are defined once per form and are active for the lifetime of the form.
But in my case the events will be per http request. So is it an overhead defining these events?
As others pointed out that pub/sub or event bus is one solution. Another solution is something like what you are trying to do here but make it more formal.
Let's take a specific example of creating a customer. You want to send a welcome email when a new customer is created in the application. The domain should only be concerned with creating the customer and saving it in the db and not all the other details such as sending emails. So you add a CustomerCreated event. These types of events are called Domain Event as opposed to user interface events such as button click etc.
When the CustomerCreated event is raised, it should be handled somewhere in the code so that it can do the needful. You can use an EventHandlerService as you mentioned (but this can soon becomes concerned with too many events) or use the pattern that Udi Dahan talks about. I have successfully used Udi's method with many DI Containers and the beauty of the pattern is that your classes remain SRP compliant. You just have to implement a particular interface and registration code at the application bootstrap time using reflection.
If you need further help with this topic, let me know and I can share with you the code snippets to make it work.
I have implemented Udi Dahan's implementation as pointed out by #Imran but with a few changes.
My Events are being raised in a Service Layer and for that using a Static Class dint seem right. Also have added support for async/await.
Also going down the Events & Delegates path did work out but it just felt like an overhead to register the events per request.
I have blogged my solution here http://www.teknorix.com/event-driven-programming-in-asp-net
I'm trying to implement Blackjack via Visual Studio, but have just been introduced to it. Suppose I have a PictureBox representing a card in a hand. This box starts with an image of a face-down card, representing a card slot that hasn't been dealt to yet. I have a function in my Form object that changes the PictureBox image to another card image resource based on an integer parameter. This is all pretty standard.
What I'm having trouble with is actually calling the method from main. I could create a new Form object and set the auto-generated one to invisible, but I'd rather work with the form that's auto-generated. Should I just put all the game logic in the Form1.cs file? Does the auto-generated form object have some default name I can use?
I realize this seems pretty novice level, but it seems like Microsoft's support documentation would prefer you create entire projects from the designer view and doesn't help much for actually coding.
The typical model for a simple Forms program is to allow the Main() method in Program.cs to remain in its default form: set some things up, create an instance of your primary Form subclass (the class name by default will be Form1), and pass that to the Application.Run() method.
It is good design to have a "controller" object outside of the UI object. But especially if you are starting out, you may well find it simpler and easier to understand if that "controller" logic is also in your primary Form subclass.
In that case, yes…all of the code winds up in the one .cs file, and indeed in the one object.
Even with the controller logic in the Form object, you will still find it useful to keep the code that is essentially controller logic separate from that which is user-interface logic, and to use the C# #region directive to label these sections of code. That will help you keep a mental model that still separates the two roles within the same class.
Beyond this, there are lots of differing opinions, from the complete "shoot-from-the-hip" approach, to the extremely strict and rigorous adherence to specific design patterns. But the above is consistent with the pattern that the Visual Designer leads you to, and so is a fine place for beginners to start.
I am writing a websocket test application that will have a GUI to send various commands over the websocket. Rather than pack all the control code (message construction, formatting, control) into the callbacks for various controls, I am considering having each GUI element callback (e.g., onClick) send an event to a delegate that can handle it. That way the GUI would be separate from any control code. Is that a 'sane' design, or is there another 'best practice' to separate the two parts.
An example would be a TV Tuner control -- the user can enter a channel number via textbox, which will have no effect until they click the 'Tune' button. The onClick method could retrieve the channel number from the textbox, and send a doTune(channel) event to the delegate to make it happen.
Thoughts/advice welcome.
Thank you,
bp
This is indeed a sane design. I personally won't go for an event call, just a regular call to a static 'SocketCommands' class will do.
That is indeed a very sensible design - what you're doing is promoting a good seperation of concerns between the presentation layer (UI) and the business layer (transaction scripts, domain services etc).
So to answer your question, yes, it is a sane design :)
With regards to thoughts/advice, that would be a topic for programmers.stackexchange.com rather than here..
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.