wondering aloud if you could embed the Boo file directly into your assembly for cleaner implementation....
First of all, great idea Keith! That actually crossed my mind as well, though I didn't follow through with it. But after seeing that I wasn't alone I decided to give it a shot. After a few nights' of trying, borrowing some code from another project, and spending some quality time with Rhino.Commons.dll in
I borrowed some code from a mutation tester I've been working on to copy the manifest resource streams from an assembly to disk. You'll notice a File.Move(...) at the bottom of the method. The filename generated by the Path.GetTempFileName() call has a randomly generated extension. Unfortunately the RhinoContainer() constructor specifically looks for the .boo extension when it tries to read the file, otherwise it tries to load the file as XML. This means that for RhinoContainer() to recognize the file, we have to explicitly change the extension to .boo. Here's the code...
/// <summary>
/// Unpacks the specified manifest resource to a temporary location on disk and returns
/// the full path of the new file.
/// </summary>
/// <remarks>The extension of the newly created file is changed to <c>.boo</c> so
/// that it will be recognized by the <see cref="RhinoContainer"/> as a Boo
/// configuration file.</remarks>
/// <param name="resourceName">The fully qualified name of the embedded resource.</param>
/// <returns>The full path to the new file containing the unpacked resource.</returns>
public static string UnpackBooConfigurationFileToDisk(string resourceName)
{
string fileName = Path.GetTempFileName();
Assembly assembly = Assembly.GetExecutingAssembly();
using (Stream resourceStream = assembly.GetManifestResourceStream(resourceName))
{
using (StreamReader reader = new StreamReader(resourceStream))
{
string contents = reader.ReadToEnd();
using (StreamWriter writer = new StreamWriter(fileName, false))
{
writer.WriteLine(contents);
}
}
}
string fileNameWithBooExtension = Path.ChangeExtension(fileName, ".boo");
File.Move(fileName, fileNameWithBooExtension);
return fileNameWithBooExtension;
}
Now that we have the stream unpacked as a physical file, we simply pass the filename to the RhinoContainer constructor, just as before...
/// <summary>
/// Determines whether this instance can successfully interact with a mocked commerce service.
/// </summary>
[Test]
public void CanQueryCommerceService_Mocked()
{
string booConfigurationFile =
Utility.UnpackBooConfigurationFileToDisk("ServiceLayer.Tests.CommerceService.boo");
IWindsorContainer container = new RhinoContainer(booConfigurationFile);
ICommerceService service = container.Resolve<ICommerceService>("mockCommerceService");
Assert.AreEqual("9.99", service.GetPrice("The Shins - Chutes Too Narrow"));
}
Now we have a much cleaner implementation which doesn't result in an random .boo file having to be distributed with our application!
I've added a new sample application showing this technique, feel free to download it and take it for a spin!