c# Winforms - Passing control references between classes/dll's - c#

I have written a piece of software that supports plugin architecture. On the main GUI is a TextBox that I use to update the user with the status of the processes.
When I load a plugin, is it bad practice to pass a reference for that Textbox through to the plugin so that it can update it from within. Is this too highly coupled? Would it better practise with events?
Thanks.

I would suggest that you create an interface for communications between the plugin and its host. That would have an UpdateStatus method, and the implementation would update the textbox.
If you really only have one thing to do (updating the status) then you could use a simple delegate... but it seems likely that you may need more operations over time.

Related

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.

MVVM communication with Objects

I'm currently trying to create an application with Prism and I have some problems with communication between modules.
I have a StatusModule which basically shows Statusmessages, but can also show the user that some work is in progress (indeterminate), show different icons, show / hide the control and so on.
For that normally i'd use a status object that has all these properties and use it as a parameter, but because in prism strong coupling is advised I don't know how I should do it.
Creating 4-5 Events for every property is probably bad practice, .. i also thought of creating an interface in my "Interaction" Module where the event's and resources are.
What would you guys recommend?
Many events for status might indeed not be the best solution; however if there's one or two that are used a lot (like showing a status message in a statusbar), I would expose them as events anyway for convenience.
For the rest, you can expose the StatusModule, or rather an interface IStatusModule that is implemented by StatusModule, via MEF or Unity depending on what you use. This way any component that wants to show status imports the IStatusModule and uses it.

C# GUI & delegate use as abstraction layer

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

How do I make a class library that works in ASP.NET and non-ASP.NET applications?

I want to write a class library that works in ASP.NET and standalone applications. Some differences in behavior are needed when running under ASP.NET. What is the recommended way to check if the library is running in an ASP.NET application?
I can check HttpContext.Current, as it appears to reliably return null when not running under ASP.NET. However, when running on a background thread in ASP.NET, it also returns null.
Any opinions on HttpContext.Current or other solutions?
ADDED: Thanks for all the advice on how to achieve a separation of concerns. However, I would like to add that this library will not be for general-purpose use, so for my particular case I do not need a lot of flexibility. In my mind, the best so far (not mentioned in this thread) is to check the HttpRuntime.AppDomainAppId static for null as it seems to work okay even for ASP.NET background threads. However, the various solutions contributed here will surely be helpful to others with more general needs.
I would push all the code common to both ASP.NET and desktop applications into a core library and test this, then create libraries that sit above the core application to provide deployment specifics - your HttpContext calls for example. You can then test reliably in both scenarios, knowing you only have to test the core application block once.
With regards checking HttpContext from a background thread - this doesn't make sense and will always return null because HttpContext is defined by the asp.net request processor. If your code starts a background thread, HttpContext will be null in the new thread. Sorry about that :)
As a work around you could try adding each new session to a global collection
and then call into the collection from the background thread. You'd need to be careful about synchronising access to your session collection though..
I think it's pretty common to separate your UI code from your application logic.
I would put all of your application logic into the shared library. Raise events from the library as appropriate. You can then handle those events in whatever app you'd like Asp.Net, WPF, etc.
If your applications needs things that might be in HttpContext, like session, you should pass those variables in as arguments to your methods so the library does not rely on HttpContext.
One approach you could take is to factor out the behaviors that vary between Web and non-Web applications into classes with a common interface (i.e. IPlatform), then use an IOC container or dependency injection to configure your application to use the proper IPlatform implementation. However, this could be over-engineering, depending on your needs. You may want to add to your question the specific behavior you want to vary among platforms.
Why not, instead, have a public property that the calling code can set to tell instances of your class whether they should use the logic they intended for ASP.NET?
Accessing HttpContext when you don't really need it, along with not working right in all cases (as you've discovered), is giving that class too much reach back into its environment. Let it simply perform its job, and let the calling code tell it which set of logic to use.

Register User Interface Elements in Engine / Controller

I am currently writing a little game with standard UI controls.
It is working great so far but what I don't like is that I am managing the controls in the codebehind file. (C#)
As I am trying to decouple all elements, I would like to have a separate engine / controller which handles all the data management and the logic for my user interface.
Is there a possibility to register the controls with the engine so that I don't need to pass them down with every method I call?
Currently I am forced to pass the controls every time I call the function..
Thanks in advance!
Will be good if you can elaborate more on your current implementation. From what I can understand, instead of trying to figure out how to 'register the controls with the engine', why not try to see if it's a design issue.
Perhaps there's a better way to structure your app/classes/components so that you can decouple logically for better reusability and maintainability?

Categories