Now that we've covered the high-level concepts and
technologies involved, we can take a closer look at our particular
implementation. The engine of this application is in the ServiceBroker
assembly. As stated in Part 1, this is
what contains the definition of the required ServiceEntryPoint attribute and
the IService interface. It also contains the code the does the actual loading,
starting, stopping, and unloading of managed services, including the
RemoteServiceHandler type that we use to remotely interact with types in the
child AppDomains.
The ServiceBroker class is the core engine class that the
.NET Service Manager Windows service code calls when a change is made, either
to the service state itself or to the directory that it is set up to monitor.
The first part of the ServiceBroker class (Listing 1) contains the declaration
of several HybridDictionary static/shared instances that are used to cache data
and references to the managed services. I chose the HybridDictionary type
because it is the best performer for collections that will typically be small
but could become larger.
Listing 1 – Dictionaries
private HybridDictionary serviceNames =
new HybridDictionary(10);
private HybridDictionary serviceAppDomains =
new HybridDictionary(10);
private HybridDictionary services =
new HybridDictionary(10);
private HybridDictionary serviceLastModified =
new HybridDictionary(10);
The serviceNames and serviceLastModified dictionaries are
used to simply cache some data about the loaded services; serviceNames uses the
path to the original assembly location as a key and the
ServiceEntryPointAttribute.ServiceName value for that managed service as the
value, and serviceLastModified uses the ServiceName as the key and the DateTime
that the assembly for that service was last modified. The other two contain
references to important objects-serviceAppDomains stores references to the
dynamically-created AppDomains, using the ServiceName as key, and services
actually contains references to the RemoteServiceHandler that is used to
control the managed service remotely in its corresponding AppDomain.