I have been asked to write an application that is going to act as a controller for a number of other external applications. It will run as a scheduled task and its purpose will be to process any new files it finds in a certain location and call external handlers depending on the file type to process them.
The controller application will have to wait until the handler application has finished before calling the next and will also need to know whether or not it was successful.
There is an added complication in that some of the files may be software packages and its possible that a software packages purpose may be to update the controller application itself. For this reason whatever framework I use has to take this into account.
Basically Im just looking for some design inspiration here to try and figure out a robust method of decoupled communication between controller and handler.
I think you have two quite separate problems:
It would be helpful if you could describe in more detail what these handlers look like. Are they .NET assemblies that have classes implementing a handler interface? If its like that, then I’d almost suggest using MEF to locate and load the handlers and execute them. MEF might make the location and loading of these handlers alot easier.
Self-updating applications are always somewhat tricky. One way that I’ve solved this problem is to have a two-part application. The first part is a small bootstrapper application that is just knows how to startup up the controller. Essentially, it’s the bootstrapper’s job to locate the controller application and launch it. The way I’ve done this is to have a directory that contains one subdirectory for each new version of the application that I’ve deployed. The bootstrapper simply picks the highest version and launches the controller application it finds in that directory.
Sample controller directory structure:
When an update is applied, all that happens is a new “version” directory is created in the controller directory and the update returns a code to the controller specifying that a restart is required. Once the controller has completed it’s work, it exits. Since the whole process was started by the bootstrapper (and the bootstrapper blocks when it launches the controller), the bootstrapper regains control when the controller launches. The bootstrapper simply executes it’s startup process again, finds the new controller version, and launches it.
The one catch here is that it’s not easy to update the bootstrapper, but typically this won’t be something you update very often as it contains very little code.
Hope that helps or sparks some ideas.