Thursday, July 17, 2008

Castle Windsor RC3 Detests MSTest?: DeserializeElement cannot process element configSections

 

I'm exasperated getting Castle Windsor to work with MSTest.  For once, it's not the other way around :)  Here's the partial code tries to resolve a database provider using Windsor.  The App.config in my MSTest project is copied to a TestResults folder with a *.dll.config extension [I didn't know .Net started allowing .dll.config files.  Well may not be, but that's a topic for another post!). 

Here's my app.config [ThinkFarAhead.WordReporter.Data.UnitTest.dll.config]:

    1 <?xml version="1.0"?>
    2 <configuration>
    3   <configSections>
    4     <section name="castle"
    5         type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" />
    6 
    7   </configSections>
    8 
    9   <castle>
   10     <components>
   11       <component id="DbTypeSql"
   12             service="ThinkFarAhead.WordReporter.Data.IDbCreator"
   13             type="ThinkFarAhead.WordReporter.Data.SqlDbCreator, ThinkFarAhead.WordReporter.Data">
   14       </component>
   15       <component id="DbTypeOracle"
   16             service="ThinkFarAhead.WordReporter.Data.IDbCreator"
   17             type="ThinkFarAhead.WordReporter.Data.OracleDbCreator, ThinkFarAhead.WordReporter.Data">
   18       </component>
   19       <component id="DbTypeOledb"
   20             service="ThinkFarAhead.WordReporter.Data.IDbCreator"
   21             type="ThinkFarAhead.WordReporter.Data.OleDbDbCreator, ThinkFarAhead.WordReporter.Data">
   22       </component>
   23       <component id="DbTypeOdbc"
   24             service="ThinkFarAhead.WordReporter.Data.IDbCreator"
   25             type="ThinkFarAhead.WordReporter.Data.OdbcDbCreator, ThinkFarAhead.WordReporter.Data">
   26       </component>
   27     </components>
   28   </castle>
   29 </configuration>
Here's the code that tries to inject dependencies:

   37         private static string WindsorConfigFile;
   38         static DbCreatorFactory()
   39         {
   40             WindsorConfigFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile; //  set // "Windsor.config"; //string.Format(@"{0}\Windsor.Config", Path.GetDirectoryName(Assembly.GetExecutingAssembly().CodeBase));
   41         }
   42 
   43         //Removed statically typed enum [that cannot be extended at runtime]
   44         //Here at least other clients can pass anything
   45         public static IDbCreator GetDBCreator()
   46         {
   47             WindsorContainer container = new WindsorContainer(WindsorConfigFile);
   48             IDbCreator creator = container.Resolve<IDbCreator>(UserPreferences.Instance.LocalDataStoreChosen);
   49             return creator;
   50         }

Here's my MSTest code:

   69         [TestMethod]
   70         public void CheckObjectCreation()
   71         {
   72             string[] databaseTypes = new string[] { "DbTypeSql", "DbType.Oracle" }; //, "DbType.Oledb", "DbType.Odbc"};
   73             Type [] dbCreators = new Type [] { typeof(SqlDbCreator), typeof(OracleDbCreator)}; //, typeof(OracleDbCreator), typeof(OleDbDbCreator)
   74             for (int i = 0; i < databaseTypes.Length; i++)
   75             {
   76                 UserPreferences.Instance.LocalDataStoreChosen = databaseTypes[i];
   77                 if(!(DbCreatorFactory.GetDBCreator() == dbCreators[i]))
   78                 {
   79                     Assert.Fail(string.Format("Type {0} instantiated incorrectly for key {1}", dbCreators[i].ToString(), databaseTypes[i]));
   80                 }
   81             }
   82         }

It fails with:

CastleWindsor-1

 

Technorati Tags: ,

6 comments:

Roelof said...

When using the app configuration file you should initialize Windsor usin XmlInterpreter, like this:

container = new WindsorContainer(new XmlInterpreter());

Read the conig docs at http://www.castleproject.org/container/gettingstarted/part1/config.html for more background

Vyas Bharghava said...

Thanks! I'll try this and let you know [I'm sure it'd work :)]!

Vyas Bharghava said...

Well, I'm getting a new error now after I changed the line to:

WindsorContainer container = new WindsorContainer(new XmlInterpreter());

and putting my castle config into App.config (instead of separate file as I was trying. If I want to use a different file, I found I need to include it in App.config)

Now the error is:
System.Configuration.ConfigurationErrorsException: The type name ThinkFarAhead.WordReporter.Data.IDbCreator could not be located.

For VS.Net 2008 Unit Tests AppDomain.CurrentDomain.BaseDirectory is:
c:\Program Files (x86)\Microsoft Visual Studio 9.0\Common7\ide

But Windsor dll and others [inclduing the one that requires to be loaded] are all in some other folder on D drive:
D:\<sourcefolder>\TestResults\Administrator_VYAS-QUAD 2008-07-17 20_43_39\Out

Would this cause a problem?

Roelof said...

You're missing the assemby name on the service="ThinkFarAhead.WordReporter.Data.IDbCreator". Changing it to service="ThinkFarAhead.WordReporter.Data.IDbCreator, ThinkFarAhead.WordReporter.Data" will solve the type load exception.

If you'd like to use a separate config read http://www.castleproject.org/container/documentation/trunk/usersguide/externalconfig.html. Also make sure you set the file property 'copy to output directory' in VS.NET to something else than 'do not copy'.

Vyas Bharghava said...

Great eye!!! Roelof, I can't believe how dumb I've been (didn't mean to sound I think I'm smart :))!!!

Thank you sssssssooooooo much...

Anonymous said...

The French gourmet cheese Bleu d'Auvergne has a wonderful aroma, a rich taste; the saltiness increases with the incidence of veining. The overall flavor is piquant but not overly sharp. Bleu d'Auvergne started life as an imitation of Roquefort, using cow's milk in place of sheep's milk. Legend has it that a peasant, around 1845, decided to inject his cheese with a blue mold that he found growing on his left-over bread (the motto being, waste not, want not). And thus, the gourmet cheese Bleu d'Auvergne was born. This French gourmet blue cheese comes from the region of Auvergne and the cheese is made from milk of Salers and Aubrac cows. The rind is very thin and so the cheese is usually wrapped in foil. The cheese is rich and creamy with a pale yellow color and scattered holes and well-defined greenish-blue veining. We cut and wrap this cheese in wedge of 8 ounces and 1 pound.

buy fresh blue cheese

[url=http://riderx.info/members/buy_5F00_fresh_5F00_blue_5F00_cheese.aspx]buy fresh blue cheese[/url]

http://riderx.info/members/buy_5F00_fresh_5F00_blue_5F00_cheese.aspx