The main proupose of this article is to develop a generic WCF host implementation, to help when developing WCF services inside Visual Studio 2005.
Background
When you need to develop a WCF service, you need to host it somewhere. So far, you have three options: IIS 6.0 (HTTP only), IIS7/WAS (Windows 2008/Vista) or self host (console application, windows service, etc).
A quick look at several development sites shows developers mostly ends up coding their own WCF host using a desktop application. The main reasons are habitual: it's cheap, it's easy, it's fun. Create a new console application, add a reference to WCF project, five lines of code and you are ready to go.
Inside a few other sites, you can see people writing windows services to host their services. But you can easily note some drawbacks of this approach: errors are written at Event Viewer, assemblies exclusively locked (so you can't rebuild that assembly) and some aditional steps to stop/recompile/restart the host (mav wrote a tip about that).
To help with this cenarios, I wrote a generic console host which receive notifications when that assemblies are rebuild, dropping their AppDomains and starting a new one. To avoid a boring almost static black screen, I also display some information about the messages received and sent throught this host, and exceptions that can be thrown.
While I don't have an extense experience using AppDomain, this implementation runs pretty smooth in my environment and I could sucessfully drop that windows service.
Using the code
We start configuring the FileSystemWatcher object and looking for all assemblies which already resides inside configured directory.
Collapse
static void Main(string[] args)
{
string pattern = ConfigurationManager.AppSettings["Pattern"] ?? "*.dll";
string dropPath = ConfigurationManager.AppSettings["DropPath"] ??
Environment.CurrentDirectory;
FileSystemWatcher fsw = new FileSystemWatcher(dropPath, pattern);
fsw.NotifyFilter = NotifyFilters.LastWrite;
fsw.Created += new FileSystemEventHandler(fsw_CreatedOrChanged);
fsw.Changed += new FileSystemEventHandler(fsw_CreatedOrChanged);
fsw.Deleted += new FileSystemEventHandler(fsw_Deleted);
foreach(string assemblyFile in Directory.GetFiles(dropPath, pattern))
{
Create(assemblyFile);
}
fsw.EnableRaisingEvents =
true;
Console.ReadLine();
CloseAll();
}
Be aware some events will fire up multiple times. Since we can do nothing about it, lets look into that delegates.
Collapse
static void fsw_Deleted(object sender, FileSystemEventArgs e)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("{0} : {1}", e.ChangeType, e.Name);
Remove(e.FullPath);
}
static void fsw_CreatedOrChanged(object sender, FileSystemEventArgs e)
{
Console.ForegroundColor = ConsoleColor.Yellow;
Console.WriteLine("{0} : {1}", e.ChangeType, e.Name);
Update(e.FullPath);
}
A small thing I miss since Clipper 5.2: colorful writing at console! This time without ANSI.SYS :)
This point is simple like that. We just need to know what files has been changed or deleted, and update our application domains accordly.
.... still formatting code....