Tuesday, February 22, 2011

Anatomy of a Windows Service - Part 3

After going through the remaining work I had planned for our service specimen, I realized that the resulting post would be very long, and so I have decided to extend the series by one more post. This week we give the app a job, and add logging.

We've spent enough time working on this service so far that we should probably give it a job at this point.  You may have guessed from the name by this point that I've been intending to make this a "hello world" for services. The types of things that services typically do are either to respond to system events or network communications, or to process units of work as they become available. A nice easy job we can give to our service is to touch a file on a very short interval--an interval short enough that a scheduled task isn't appropriate. Let's say 5 seconds.

We'll worry about handling the interval later. For now, let's just add the behavior so that it happens once, when the service starts.

First we create a straightforward little task-oriented class and interface. This should require no explaining. And of course we'll register this with the IoC container as well. You should be familiar with that code by now, so from here on out, I won't mention the IoC container unless something out of the ordinary is required for the registration or resolution.


With this done, we add a dependency to the interface in our GreetService constructor, and then a call to the task in OnStart.


This will cause the C:\Hello\World.txt file to be created when the service starts. The service will then be running, according to the Service Control Manager (SCM), and can be stopped. But while running it will do nothing more. If you want to see the full sample project source at this point of progress, I have tagged it in the GitHub repo.

This is a good time to add some logging. If we have problems later on, logging will help us to troubleshoot what's going on.  Right now, if the service were to fail somehow, we wouldn't know why. If AutoLog were set to true in the service contructor, then the service would log to the Application event log when it crashed, but not with much useful information. But we don't want that anyway, if our log is an important one. Rather it should have it's own log, so we can always be certain we're looking at the right info and we don't have to sift through hundreds of other entries to find it.

Adding a custom event log is actually quite simple. There are two parts to the task. One is to make sure it gets created when the service is installed. The other is to use it. Creating an event log on install is trivial, mostly because it's already being done, and we can just hook our own data onto that. That's right, the ServiceInstaller class by default contains an EventLogInstaller that is configured to install an event source for our service in the Application event log. All we need to do is override that with our own log and source name.

Since both the installer and the logger class we'll write will need to know those two pieces of text, we'll create a settings provider for them. This will allow us to control the values for both usages in a single place.


Now that we've got a source from which to obtain the proper names, we can add a dependency to our service installer, and use it to override the default event log settings. All we need to do is pull the default EventLogInstaller out of the ServiceInstaller.Installers collection, and change the properties.


When we go to install the service using InstallUtil we will see it output that it is creating a new event source and event log. And if you go to the Windows Event Viewer in the Administrative Tools, you'll find a log called GreeterService.

Of course in order for anything to show up in there, we'll need to log some things to it. The safest way to do that is to throw in a logger object that can try to log to the event logs, but which won't crash out if it can't.  The last thing we want is for the service to crash due to a log issue if the work itself is humming along. (Unless, of course, we need an audit trail or something, but that's a different story.) Note the explicit exception suppression in the logger class below for this purpose.


This logger could be enhanced in a few ways, for more serious services. One good thing to do is to support different "levels" of logging. I have four standard levels that I use. In increasingly voluminous order they are: fatal errors, exception cases, progress, and verbose. An enum parameter added to the logging methods would allow the logger to check to see if it's in a mode that should allow an entry for the specified level. A step further, we might replace the String parameters with Func callbacks. The callers can place the actual work of assembling the message into these callbacks, and the logger would only call them if it had determined that the logging would be performed. By only doing the string manipulation if it is absolutely necessary this keeps performance up and avoids unnecessary failure points.

With the logger object available it would be a good idea to add some logging when the service is starting and stopping. Here are the updated OnStart and OnStop methods from our GreetService class:


Now you can install the service using InstallUtil.exe, and when you start and stop via the SCM, you'll see entries show up in the GreeterService event log.

We'll stop here for now, as this post is getting long and there is much more to do. You can see the full service code to this point so far where I have tagged it in the GitHub repo. Next time will be our final (I promise) post in this series. We'll bring it home by figuring out the best way to make sure the service does its work when we want it to, and then making it easily configurable, and reconfigurable.

Tuesday, February 15, 2011

Satisfying A Pair of Same-Typed Dependencies with Autofac

We'll take a break from the series on Windows services this week and cover some more Autofac / IoC / DI material. I hope to finish the services series with the final part next week.

Back in December I wrote a rather long post about the different Autofac relationship types. I covered what I considered to be the big ones, but there were a few that I didn't cover: IIndexed, and Keyed. I had an objection to these types that prevented me from examining them any further.

My Initial Objection

It's pretty simple. I don't want to have to reference the the IoC container framework in my classes. Accepted wisdom on IoC container usage is that you shouldn't reference the container, and I viewed this as an extension of that. Indeed I prefer to avoid referencing such infrastructure frameworks in core code wherever possible.

I feel the same way about the BCL's TypeConverterAttribute, and the XML serialization attributes, for example. It's an insidious form of coupling, and I really prefer to avoid having these little signposts sprinkled throughout the code of what framework I'm working with. Especially if they represent things that I can't sub out for testing, as is usually the case with the BCL.

In addition to the framework reference objection, I felt that this was just not a responsibility that belonged to the subject class. Using special parameter types or the like to denote such information was "cheating", akin to service location, and undermined the principle of Inversion of Control.

The purist in me had dug in on two separate fronts, and was ready for a fight. But recently I had an experience that taught me the value of these relationship types: I found I needed to inject two different implementations of the same service in the same place. I initially shied away from these relationship types. Instead, I decided I could solve the problem with a clever registration/configuration. After all, deciding who gets what implementations is what that's all about, though typically in a more generalized sense.

The Problem

My situation was that I had needed two different runtime instances of an image cache. One for full-size images, and one for thumbnails. And most commonly I needed to reference both of them in the same scope. If the two use cases existed in different contexts, I could possible use Autofac's nested container support to identify each one appropriately when needed. But in my scenario, I actually had a couple of classes that needed to make use of both caches. I gave the constructor for that class two parameters for injection, both having a datatype of the cache interface type. Then I went to work setting up the registration.

Without a major redesign, the solution has to involve attaching some metadata to each of two separate instances registered with the container. The container needs some way to differentiate between the instances. Since Autofac provides it, there's really no reason at all not to use the keying facility for registration. Given an interface ICache and an implementor Cache, the registration would look as below.


Now let's introduce another class that needs to use both of these caches.


Again, my instinct is to say that the class shouldn't have to say anything else. It's the container's job to figure out how to fill those dependencies. But what information does the ImageBrowser class expose that the container registration could use to determine which argument gets which instance of ICache? Well right now, there's not much there. Pretty much just the argument names. Can we use those to assign the ICache instances? Yes, but it ain't pretty.

OnPreparing1

The way to access the parameter names for resolution is to hook the OnPreparing event, as seen here:


Our implementation of OnPreparingImageBrowser then looks like this:


This looks harmless enough, if a bit verbose. But is a problems. We have encoded parameter names in strings in our registration code. If we ever have to change those parameter names, or add more dependencies to the constructor, this registration code for ImageBrowser will be broken, but it will still compile. So unless you have some pretty magnificent tests for your IoC registration (which it seems is not easy to do), this is a regression bug waiting to happen. Furthermore, this code is very likely useless even if we have another class with these same dependencies. If the constructor arguments are named differently, we'll need another delegate for that set of constructor arguments.

So obviously argument names aren't the ideal way for the subject to communicate information about multiple dependencies of the same service type. And even using the argument names undermines my objection in spirit. It just does it implicitly, rather than explicitly. So let's just accept that we've already taken the first step and go the rest of the way. How can we communicate the necessary information in a sustainable way, that doesn't require us to go mucking around in the registration code if we shuffle things around a bit in ImageBrowser?

Three options spring to mind. One would be to use an attribute applied to the arguments of the constructor. But there's no native support for recognizing these in Autofac, so we'd have to write our own registration and resolution conventions. While it would be more resistant to change than the named parameter mechanism, it would require even more code on the registration side of things, to set up a convention-based registration that keys on the attributes. Not to mention having to define the attributes. This actually sounds like a fun exploration for another day. But today, we just want to get this working with a small amount of intuitive code.

Autofac has two mechanisms which we can use to reduce the amount of code we need here: IIndexed and Meta.

IIndexed<TKey, TComponent>2

Using Autofac's IIndexed mechanism is a simple change from where we are now. It involves a small change to the constructor of ImageBrowser, and removing code from the bootstrapper. That's right, a net reduction in code, without losing functionality. And there's nothing better than a good codectomy. So grab the scalpel and sculpt our new bootstrapper.


Note the removal of the OnPreparingImageBrowser method, and the reference to it in the ImageBrowser registration. That's the only change here. It's completely unnecessary code. The cache registries don't need to change because the IIndexed mechanism hooks right into the keyed registration just like our old strategy did.

The ImageBrowser constructor needs to change a bit to trigger resolution using the keyed registration. Here's the updated class:


The only change here is that we consolidated the separate cache arguments into one dictionary-style argument.

Meta<TComponent>3

Autofac's Meta mechanism works a little differently in that it allows you to attach data to a registration, and then to express a dependency on that metadata, in the subject class. The data takes the form of name/value pairs. If we wanted to use this, it would change our registration as follows:


We've replaced the call to Keyed with a call to WithMetadata. We also are essentially passing a name-value pair. There's also the option to attach an actual custom metadata object, and use the property names and values as the name/value pairs. Since we only need the one value, and it's not going to be changing at runtime, we can just directly assign the name and value easily.

Once again our constructor will need to change, of course. Here's the version that uses the metadata:


Here we're using the IEnumerable relationship type to get all the metadata objects, and then explicitly picking out the ones with the two with the values we're looking for. The CacheTypeChecker method is just a little comparison delegate generator that saves a bit of repeated code in the constructor.

The Lesser of Two Evils

Now this isn't necessarily the problem that Meta or IIndexed are meant to solve. It's really more meant for cases where the needed component is going to depend on runtime conditions. In that case, a simple service finder/locator is sometimes exactly what you want. There are often other ways to get the job done even then however, for example using lifetime contexts and contextual state objects to give the container all the information it needs.

In our case though, the dependency that's actually being injected bothers me a bit. It's sort of a limited service locator. The problem with that is that the specific dependencies aren't explicit. ImageBrowser is basically saying, "Er, I can't tell you exactly what I want, but if you give me everything like this, I'll pick out the ones I want". That is definitely not a pure inversion of control in this case, because we need exactly 2 instances of a very particular type.

We're basically limited to choosing the lesser of two evils. Do we couple to constructor argument names, or take a dependency on a service locator? I'm not sure I feel more strongly about either one. But the IIndexed option is definitely the least code, so that's the one I'll go with. And you can bet that if I run across a situation where the decision of which instance I need is made at runtime, I'll look to these solutions first.

Somewhere down the line I'll investigate that attribute convention option I mentioned in passing. I tend to dislike attributes, but if it's our code (rather than framework code) that does both the defining and the consuming... then maybe I can live with it.



GitHub Source Code References
  1. Keyed registration with OnPreparing resolution
  2. Keyed registration with IIndexed<TKey, TComponent> dependency
  3. Metadata registration with Meta<TComponent> dependency


Tuesday, February 8, 2011

Anatomy of a Windows Service - Part 2


This post contains gist code samples. My experiments indicate that these do not display in Google Reader, so if you are reading this there, you may want to click through to the post.

Last time, we dissected a Windows service template project to get a handle on the different moving pieces.  We identified an installer class, as well as two run-time configured installer objects, a service class, and the framework injection point for spinning up a service.

The template is a very simple project, and it gets the job done.  There are some deficiencies though.  From an architectural standpoint, the design doesn't lend itself well to testability, or composability.  It also doesn't provide any good place to bootstrap an IoC container for the installer portion, which would be beneficial to have if we want to have any custom behavior happening at install.  From a feature standpoint, there's no logging, and no worker thread to separate the service control events from the actual behavior of the app.

Let's start out by improving the composability, which will put us on a good footing for testability as well.  The biggest obstacle to that in the template project was all of the direct instantiation and configuration of objects.  For example, in the template project, the ProjectInstaller class's constructor, which is an entry point that is triggered directly by msiexec or installutil, was responsible for creating and initializing the sub-installers.  In our application, we'll defer to an IoC container, rather than construct these objects directly.

Let's add a reference to my personal favorite IoC container, Autofac, and then create a bootstrapper that will do the registration necessary for the installer portion of the app. We'll leave it empty to start, because we haven't established what we'll need from it yet.


Now lets create the ProjectInstaller.  The constructor, since it's an application entry point, will have a direct reference to the IoC container.  We'll leave out the needless code we identified last time, but don't forget the crucial RunInstaller attribute.  The constructor is left responsible for setting up the Installers collection.  If we assume that we'll be registering all our installers with the IoC container, then Autofac makes this easy for us with the IEnumerable relationship type, which will resolve all implementors of the specified service that are available at the resolution location.  Let's put all that together and see what we get.


Compared to the template project, we've eliminated some explicit object instantiation, but we've also lost some explicit configuration.  That has to be exported to somewhere else.  There are a couple of options for re-creating this functionality with our IoC container in place.  One is to give these exact configuration responsibilities, i.e. the setting of properties after construction, to the IoC container.  This is not a strong-point of most containers--even Autofac.  It can be done, but it's not really straightforward.  It results in complex registration code that doesn't communicate well what's going on.

Alternatively, we could move these responsibilities into factories.  I've used this strategy before, and it can be advantageous if there are classes that will have dependencies on the factories themselves.  But in this case, the only thing that would need to know about the factories is the IoC.  So instead, I'd recommend deriving special-purpose sub-classes of the desired installer base classes, and putting the configuration in those constructors instead.  Here's what that looks like.



Simple, straightforward, self-contained, and single responsibility.  Now we just need to update the IoC registration to include them, and they'll get picked up automatically by the ProjectInstaller constructor.  We could take advantage of Autofac's fluent registration API and auto-wiring to do this without referencing the individual types.  But I have these two classes in separate namespaces (the service installer is in the same place as the service, because these must come in pairs), and the ProjectInstaller derives from the same base, it would actually take more code to deal with these special circumstances.  So explicit registration it is.


Note also here that we've registered these as InstancePerLifetimeScope, because there's really no reason more than one of either of these should be floating around.

That covers the install portion of the service.  We now have separated the three installation components into their own separate places.  Changes to the configuration of any one of them are isolated in their own locations in the code.  And as a bonus we've made the ProjectInstaller constructor trivially simple.

Let's shift gears and take a look at the service portion of the application.  We'll set up a blank bootstrapper for this portion as well. I'll refrain from posting the code as it's essentially identical to what I showed you for the other one.

The remaining two significant pieces that need to be implemented to replicate the functionality we saw in the template project are the service class itself, and the program mainline.  The mainline is going to be simple just like the ProjectInstaller.  In fact it's structure mirrors the installer very closely, just with different type names in a few strategic places.


I've chosen to request an IEnumerable, even though we only have one implementation.  Maybe we'll add more services to this assembly some day, and maybe we won't.  To make a decision on that basis triggers my YAGNI reflex.  I used an IEnumerable resolver just for my own aesthetic sense, because the framework runner takes a collection anyway.

Next let's look at the service class itself.  This is another class that, in the template project, had a lot of noise that we identified as unnecessary.  So in this iteration, it's going to be comparatively short and sweet.


There's very little to see here, and that's very much as it should be, since our service doesn't actually do anything yet.  We just cut out the noise and were left with something trivially simple.  So let's move on to the last piece left to put in place: the service bootstrapper.


We're just blasting through code files here, as this one is another very simple one, with just one registration.  We'll add more, but for right now we have completely matched the functionality of the template project.

Before we put the project to bed for another week, though, there's a small refactoring we can make that will make a nice little illustration of the benefits of how we've organized the project.  You may have noticed that we have some hard-coded strings in the constructors of the service and the service installer.  And particularly, there's one that's intentionally repeated, since it has to be the same in both places.  We can eliminate the hard-coded string and make sure that the values in both locations always match, by using the setting injection pattern I described a few months ago.

With just a few lines of code we can set up the necessary setting dependency.



With this class and interface in place, we can add a dependency to the constructors of the installer and the service.



And finally, in order to support the dependency injection, we just add one new registration to each of the bootstrappers.


That's the end of our work for this week.  We have replicated the template project's functionality, such as it is, and run through a lot of simple little snippets of code.  Structurally, the Solution Explorer doesn't look a ton different, but I think the code is simpler and more straightforward.  Plus we have built a good foundation on which to add the functionality that people expect of a service.  All the code for the project we worked on in this post can be found on GitHub at https://github.com/cammerman/turbulent-intellect/tree/master/HelloSvc.

Next week, we'll add logging to an event log, and we'll make it actually do some work.  Finally, we'll figure out how that work needs to get done, inline, or in one or more worker threads.

Tuesday, February 1, 2011

Anatomy of a Windows Service - Part 1


This post contains gist code samples. My experiments indicate that these do not display in Google Reader, so if you are reading this there, you may want to click through to the post.

I recently had to estimate the effort for creating a one-off Windows Service for massaging some document indexing data as it passed between a capture system and an ECM system. I was quite confident in my ability to code up the "massaging" part, but the service part was unfamiliar territory. So I decided to do some investigation and figure out just what it takes to get a service set up, what special considerations need to be made for logging and injecting configuration, and how to preserve good design sensibilities through it all.

The easiest way to create a Windows service is to use the associated project template in Visual Studio. I specifically wanted to work in .NET 4.0 for the investigation, as I would be on the actual project, but unfortunately I don't personally have a license for the full version of Visual Studio 2010, and VS Express 2010 doesn't have a project template for Windows services. Fortunately, I do have VS 2008, and the BCL infrastructure for services hasn't changed between 3.5 and 4. So I decided to generate what I could in VS 2008, add some googling, and use the combined information to create a service from scratch in VS Express.

This week, we'll analyze what VS will give us for free with the project template and special code-generating actions. We'll identify the purpose of the different pieces of code, and make note of how we can use this information to build our own service, complete with installers, from scratch.

So to start, let's take a look at the structure that the project template creates for us. Here's a shot of what the initial solution looks like in a brand new Windows Service project.


Note the two structural differences between this template project and a blank or console project. There's an extra reference to System.ServiceProcess.dll, which we'll need to remember, and there is an extra component class called Service1. There's also a .Designer.cs file for Service1, but this is really just because Visual Studio automatically adds these any time an item that is a subclass of Component is added to your project, either via a template, or the "Add New Item" command.

Before we take a look inside the service class itself, we should see how the Program class differs from other types of project templates. Here's the Program class.

There are a few differences to note here. The biggest difference is obviously that the main method contains some generated code. It actually looks similar to what is generated with the new Windows Forms project template. We have the service class, representing the actual core of the program, being instantiated and then passed to a runner method provided by the framework that handles spinning up the appropriate context.

Now lets take a look at the service class. It comes in two parts: the main class file, and the designer file. First the main class file.


The most prominent features here is the base class, ServiceBase, and the two override methods, OnStart and OnStop. ServiceBase is, of course, the common base class that all .NET windows service classes must derive from, in order to take advantage of the framework support. The overrides are two of the possible entry points into the service. They correspond directly to the actions that you can take on a service in the Services control panel. OnStart is where you would place the code that processes the arguments, spins up workers, etc. Naturally OnStop is the other end of things, where you'd put your cleanup code to prepare for termination. There's also a call to InitializeComponent in the constructor, which is typical of generated Component-derived classes. We'll see if there's anything interesting happening there next, in the designer file.


There's a bunch of generated code here, but there's actually less going on. So what is all this doing? We can easily see an implementation of a Dispose idiom, which is disposing of any components contained inside this one. But when we look back at the InitializeComponent method, the Container is constructed and then left empty. The only significant code here is the assignment of the ServiceName property. We'll need to remember this for when we create our own service class from scratch. Everything else in this file could be dropped. The ServiceName initialization could just as easily be put directly into the constructor.

What we've seen so far is the absolute minimum service. If you put some behavior into the OnStart method, you could run from the command-line, and it would operate. But it wouldn't show up in the Services control panel, because it doesn't have an installer to register it. And that means you couldn't Stop it once it was started.

What does it take to register a service with the OS? VS offers a shortcut to generate the code for this as well. If you right-click the service class Service1.cs in the solution explorer, the context menu has an "Add Installer" option, which adds a new class to the solution, called ProjectInstaller. This is the last piece of our example puzzle, and it's another two-parter. First the base class file.


There's not much code here either. Like the service, we see this is a Component-derived class, by way of Installer) with an InitializeComponent method called in the constructor. We'll take al ook inside there in a moment. First, make note of the attribute on the class. The RunInstaller attribute is a signpost for the InstallUtil.exe installer tool that comes with the .NET Framework, or for the VS Setup Package Custom Action Installer. The Boolean true argument tells the installers that that they should indeed invoke this installer class when they find it in the assembly.

The attribute is important, but it's not the meat of the class. That's found in the designer file.


The form of this file is very similar to that of the service's designer file (and any designer file, really). Once again we see the disposal idiom, and once again, the container that it disposes is never populated with anything. The body of the InitializeComponent method is concerned with creating and initializing two more installer objects. One is a ServiceInstaller, which is a class that knows how to install a particular service in the registry and such, given a ServiceBase representing it. The ServiceProcessInstaller handles install tasks common to all services, and so there should be only one inside a given project installer.

The MSDN documentation  doesn't go into any more detail about what the responsibility differences are between these two types of installer, or why they are peers, as far as the main Installer is concerned. But it is clear about how they should be used. The installer objects need to have properties initialized to indicate how the install should proceed, and then they must be placed in the Installers collection. This also could just as easily be done in the constructor, eliminating the need for the designer file.

One important thing the documentation highlights is that the ServiceName property on the ServiceInstaller must match the same property on the service which it is associated with, since this is the only thing that links the service registration with the actual implementation. We'll examine the other installation-guiding properties, on both objects, in detail when we put together our own service from scratch.

For now, we've covered everything in the project template. What we have here is a complete, spartan service that does nothing. It will install, simply by compiling the executable, and then running InstallUtil.exe from the .NET framework folder against it. And it will run from the service control panel... but it has no visible side-effects.

Next time, we'll get to work replicating the moving pieces of this solution in a spanking new, blank C# 4 project. It will look a little different, structurally, but all the prominent features will still be there.

P.S. All the code that appears in this series will be available on my github page. For now, I have it in this repo: https://github.com/cammerman/turbulent-intellect. The code for this post in particular is found here: https://github.com/cammerman/turbulent-intellect/tree/master/ServiceExample35. I expect to reorganize this a bit in the future, but I'll update this link when I do so.