Tim Barcz

Sponsors

The Lounge

Wicked Cool Jobs

Groups and Affiliations

Syndication

News

Images in this post missing? We recently lost them in a site migration. We're working to restore these as you read this. Should you need an image in an emergency, please contact us at imagehelp@codebetter.com
Test Your Windsor Container Configuration

We use Windsor as our IoC container.  Currently we use xml as the method by which components are registered.  Having done both, I prefer the xml mapping to code registration because I can change something in the app on the fly if I need to. I know some of you out there will disagree with me on this but that's ok.

One of the annoyances with xml is that you have to type the namespaces and classes along with assembly names.  We've found there is friction when we refactor our classes, changing names, moving classes,  and adding namespaces in that Windsor bombs.  When using the xml for configuration you don't get compile time checking, so a successful build may not mean working code, which in my opinion is bad.

We've simply added the following test to our unit-test project.  It still doesn't fail when compiling, but fails instead when we run unit-tests, which is closer to compilation than run-time.

   1: [Test]
   2: public void Can_initiate_Windsor()
   3: {
   4:     IWindsorContainer container = new WindsorContainer("windsor.config.xml");
   5: }

That's it!  It's very straight forward because all it's trying to do is start up windsor, the same way your application would, any exception that is thrown fails the tests, which causes the build to fail.


Posted 08-27-2008 4:54 PM by Tim Barcz
Filed under:

[Advertisement]

Comments

Chris Martin wrote re: Test Your Windsor Container Configuration
on 08-27-2008 6:43 PM

Unless you use the exact same config file for your tests (which I find unlikely), this won't work 100%.

Tim Barcz wrote re: Test Your Windsor Container Configuration
on 08-27-2008 9:58 PM

@Chris

Very good point.  I should point out that the goal of this test is to test the windsor xml configuration for the application, NOT the windsor xml configration (if one exists) that drives the test project.

Matt Everson wrote re: Test Your Windsor Container Configuration
on 08-27-2008 10:59 PM

This test is great for testing XML syntax, but it won't tell you if a registered service cannot be instantiated because a constructor dependency is not found.

That's easy enough to fix by adding this:

foreach (IHandler handler in container.Kernel.GetAssignableHandlers(typeof(object)))

           {

               container.Resolve(handler.ComponentModel.Service);

           }

Patrick De Boeck wrote re: Test Your Windsor Container Configuration
on 08-28-2008 3:17 AM

Actually the following code tests your windsor container configuration.  It includes support for generics as Matt's solution doesn't:

foreach(IHandler handler in GetHandlersFor(typeof(object)))

           {

               if(handler is DefaultGenericHandler)

               {

                   Type[] genericArguments = handler

                       .ComponentModel

                       .Service

                       .GetGenericArguments();

                   foreach(Type genericArgument in genericArguments)

                   {

                       Type[] genericParameterConstraints =

                           genericArgument.GetGenericParameterConstraints();

                       foreach(Type genericParameterConstraint in genericParameterConstraints)

                       {

                           _windsorContainer.Resolve(

                               handler

                                   .ComponentModel

                                   .Service

                                   .MakeGenericType(genericParameterConstraint));

                       }

                   }

               }

               else

               {

                   _windsorContainer.Resolve(handler.ComponentModel.Service);

               }

           }

P.

Kyle Baley wrote re: Test Your Windsor Container Configuration
on 08-28-2008 10:22 AM

Bil Simser posted a couple of tips on this. The first is similar to yours but actually attempts to resolve things:

weblogs.asp.net/.../the-first-spec-you-should-write-when-using-castle.aspx

weblogs.asp.net/.../testing-castle-windsor-mappings-part-deux.aspx

Tim Barcz wrote re: Test Your Windsor Container Configuration
on 09-01-2008 2:32 PM

All,

I've expanded my test to also run through each of the components and see if they could be instantiated.

While the original test insulated us from our current pain points, the new additions are very helpful.  Thank you all for you comments.

Brian wrote re: Test Your Windsor Container Configuration
on 07-28-2009 12:57 PM

Here is a version that tests generic classes with no constraints and generic classes with multiple generic arguments (e.g. MyClass<T,R>)

       [Test]

       public void WindsorContainerMappingConfigurationShouldBeCorrect()

       {

           IServiceLocator locator = (new ServiceLocatorProvider()).GetServiceLocator(false);

           IoC.Load(locator);

           IWindsorContainer container = ((IContainerAccessor)locator).Container;

           foreach (IHandler handler in container.Kernel.GetAssignableHandlers(typeof(object)))

           {

               if (handler is DefaultGenericHandler)

               {

                   Type[] genericArguments = handler

                       .ComponentModel

                       .Service

                       .GetGenericArguments();

                   Type[][] genericArgumentConstraintMatrix = new Type[genericArguments.Length][];

                   for (int i = 0; i < genericArguments.Length; i++)

                   {

                       genericArgumentConstraintMatrix[i] = genericArguments[i].GetGenericParameterConstraints();

                   }

                   // This doesn't test every combination that can be instantiated,

                   // only the first constraint on every generic argument.

                   Type[] genericArgumentConstraints = new Type[genericArguments.Length];

                   for (int i = 0; i < genericArguments.Length; i++)

                   {

                       if (genericArgumentConstraintMatrix[i].Length > 0)

                       {

                           genericArgumentConstraints[i] = genericArgumentConstraintMatrix[i][0];

                       }

                       else

                       {

                           genericArgumentConstraints[i] = typeof (object);

                       }

                   }

                   container.Resolve(

                       handler

                           .ComponentModel

                           .Service

                           .MakeGenericType(genericArgumentConstraints));

               }

               else

               {

                   container.Resolve(handler.ComponentModel.Service);

               }

           }

       }

Add a Comment

(required)  
(optional)
(required)  
Remember Me?

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)