Introduction
In the solution I most working on we will have services for every part. Letter service to send sms and mail messages; Print service to print reports; Application service to most common utilities; Synchronization service to send update
to other systems and so...
All this services will be implemented as WCF Service Library hosted in Windows Service.
Depending on the size of the customer it is possible that all these services installed on the same physical machine. In such case we may running up to twelve
Windows services and eat resources (like memory, ports, etc.).
I decided to put together a solution to host any of these services under a single windows service. I also decided to make it flexible enough to add and remove services
as easy as possible.
Finally I came up with these features:
- Self-install / uninstall
- Console mode to debug
- Single port to all WCF Services (from configuration file)
- Endpoints created automatically from assembly / type
info (no need to server config file)
- Every type loaded into new application domain, so crash of one WCF Service will not crash others (isolated processes)
- Types loaded according interface using MEF (Managed Extensibility Framework)
I will not explain in details all the steps involved - it came to a surprisingly simple code at the end...
...and the code attached at the bottom, but will see into some of the 'gems'.
Windows Services Can Install Themselves
In the process of the making found an article by this title, and added it to my solution at once.
Read it here and pay tribute
to W. Kevin Hazzard from Code Project.
MarshalByRefObject
In all (most?) articles when talking about loading assemblies into different application domains you can find the fact that your class must inherit from MarshalByRefObject
.
It's not true. All you need is make your class Serializable (MarshalByRefObject
is also make it Serializable but also
ComVisible
!).
Enable MEF in your project is complicated
It can be the feeling after reading about MEF and checking some examples. The truth is that all you need is to implement an interface that can't be simpler (empty!).
using System.ComponentModel.Composition;
namespace WCFServiceInterface
{
[InheritedExport]
public interface IWCFService
{
}
}
(It's true that the code to load all the matching assemblies is almost 15 lines but...)
That's all folks!
You will found that it's really simple - so jump in and enjoy...