flow.
"Flow is a condition of deep, nearly meditative involvement." - Tom DeMarco

Embedding the Binsor Config File Directly in Your Assembly

Tuesday, October 16, 2007 9:37 PM
In the last post we talked about Binsor, which allows you to configure you Windsor IoC types with Boo instead of clunky old XML.  Keith Elder, was kind enough to leave this comment wondering aloud if you could embed the Boo file directly into your assembly for cleaner implementation....

Question. Is there any reason why you couldn't embed the .boo file as an embedded resource file and have it read directly from the assembly? That just seems a little cleaner to me from a deployment standpoint. Is there one? I'm just asking since I am nowhere near close to the Windsor project.

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 Reflector, I managed to get it working.

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!



kick it on DotNetKicks.com

Feedback

# re: Embedding the Binsor Config File Directly in Your Assembly

Very good Jeremy, I thought it could be done! 10/17/2007 9:29 AM | Keith Elder

Post a comment





 

Please add 8 and 6 and type the answer here: