Using Indigo to communicate with Windows Forms applications, Part II
In the first part of this series of posts, I showed you how to implement a Windows Form application that exposed itself as a service, implementing the IFooService interface. Here Part II, I’m going to explain one of the subtle aspects of the ServiceHost<> constructor that makes this application possible.
By default, Indigo creates an instance of your class for each incoming message when using ServiceHost<>’s default constructor:
_fooService = new ServiceHost<Form1>();
This makes handling multiple messages at the same time straight forward, in that the threading is handled behind the scenes for you and you do not need to worry about making your class thread-safe. However, my example in Part I demonstrates IFooService.Bar setting the text of a textbox hosted within Form1. “Bad things would happen” if Indigo were to create an instance of Form1 for every incoming message. Because Form1.textbox1 is a class member variable, each new instance of Form1 gets a new instance of textbox1, and this is not the desired behaviour. We care about Form1.textbox1 in the instance of Form1 that is displayed on the screen. To deal with this challenge, Indigo allows you to pass an instance of your service to the ServiceHost<> constructor, effectively creating a singleton of that service, and this is exactly what our Form1 class does in its constructor:
_fooService = new ServiceHost<Form1>(this);
Armed with this, we are guaranteed that incoming messages are always serviced by the already created instance passed into the ServiceHost<> constructor. By passing this to the ServiceHost<> constructor, the sole instance of Form1 handling the applications UI becomes the endpoint for messages sent to IFooService and the implementation of IFooService.Bar is guaranteed that accessing this.textbox1 will update the form’s UI.
In Part III, I’ll discuss the challenge of implementing a service in a class outside of the form and ways to deal with it.