One of the more "common" tasks in computing in general is to have some sort of service running in the background doing all kinds of different things, and as a developer, I feel it's quite nice to just have a very basic framework I can plug into whenever I need something run as a service.
In Mijan.Core I have a Service namespace which contains the basics for your own windows service, complete with installer and the potential to debug as well. This is a very simplistic concept which enables people to make complex services and just quickly plug it into a windows service.
I've defined IService as the base interface for any service, a service needs to be able to start, stop and have a name for identification purposes. The Start method also takes an IServiceHandler as a parameter, if the service for some reason needs to interact with other services running in the same application, in general this parameter can be ignored though.
For the basic executable service, all you have to do is create a console application (not a service!) and have the following in the main entry point.
You can also add another optional parameter after args to specify the name of the service as it would appear in services, otherwise it'll default to MijanService.
I've made a basic TimerService implementation that resides in Mijan.Core.Service, this performs a given task every X minutes during a specified time interval, or simply every X minutes all the time. For a very simple implementation of this, look at the following.
This is essentially all that's needed for a service to execute something every minute, in this instance TimerTick() will write the current time to the Console.
For the service to pick up on this, however, it needs to be plugged in to the app.configuration file. MijanService needs its own little configurationSection, and that's handled as such.
The HelloService line is the timer just implemented above, with its name and namespace as well as the assembly where it's located. The second example is how to specify custom values in the configuration xml. In this case I've added a few properties in another service, and need to add a separate class for the XmlConfiguration, as well as a Service to handle this. As long as I have a service constructor with an XmlElement as its parameter, it will pass its service element into the constructor to handle. For this example, the classes look like
It's important to note the [XmlRoot("service")] attribute, as that's the XmlElement being passed into the constructor.
The service executable takes 3 different parameters when you launch it, either install, uninstall or debug. If you use install, it will be added to the computer's list of services, and will function as any other service in terms of start/stop/recovery. Uninstall obviously uninstalls it, while debug will launch the service in the console window, so you can essentially have it running in a controlled environment before throwing it into fully automated service-mode.
The result and output from running this service in debug mode will be ...
Both services specified in the configuration get to run in their own threads and have their fun!