Configure Unity From FileConfigurationSource Fails

May 20, 2009 at 5:48 AM
Edited May 20, 2009 at 7:28 AM

I am unable to resolve enterprise library types (such as LogWriter, and ExceptionManager) that are correctly configured, if not using the default config source. 

Steps to reproduce:

1. Create an MSTest project with a test
2. Copy the config from the logging quick start
3. Read to FileConfigurationSource
4. Configure container
5. Try resolve LogWriter: 

 

<font size="2">

[

</font>

TestMethod]
public void TestMethod1()
{
string appConfigPath = String.Format(@"C:\Dev\EntLib41Src\Quick Starts\Logging\CS - UnityIntegration\LoggingQuickStart\bin\Debug\Copy of LoggingQuickStart.exe.config");

IConfigurationSource configurationSource = new FileConfigurationSource(appConfigPath);
UnityConfigurationSection unityConfigurationSection = (UnityConfigurationSection)configurationSource.GetSection("unity");<font size="2">

 

</font>

 

// Create a new unity container and configure it from config source
var unityContainer = new UnityContainer();
unityConfigurationSection.Containers[
"loggingContainer"].Configure(unityContainer);<font size="2">

 

</font>

 

// Test Fails Here
var
logWriter = unityContainer.Resolve<LogWriter>();

 

}

Any suggestions? This works if you run this code in the Main() method of the Logging Quick Start with Unity, not sure why it would fail under MSTest??

<font size="2">

[

</font>

STAThread]<font size="2">

 

</font>

static void Main() {
string appConfigPath = String.Format("Copy of {0}.exe.config", Assembly.GetExecutingAssembly().GetName().Name);
IConfigurationSource configurationSource = new FileConfigurationSource(appConfigPath);

<font size="2">

 

</font>

UnityConfigurationSection unityConfigurationSection = (UnityConfigurationSection)configurationSource.GetSection("unity");
var unityContainer = new UnityContainer();<font size="2">

unityConfigurationSection.Containers[

</font>

"loggingContainer"].Configure(unityContainer);
var logWriter = unityContainer.Resolve<LogWriter>();

...
}

May 20, 2009 at 8:07 AM
Edited May 20, 2009 at 8:09 AM

What code throws exception and what is the exception?  I'm not sure that you reached the call to Resolve method.  I was able to resolve an instance of LogWriter using the same config and using an IConfigurationSource. 

 

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.

entlib.support@avanade.com

May 20, 2009 at 8:11 AM
Edited May 20, 2009 at 8:40 AM

This occurs when running the MSTest.

TestMethod
public void
TestMethod1()
{

   // ... See first post for code listing

  // Blows up trying to resolve LogWriter 
var
logWriter = unityContainer.Resolve<
LogWriter>();
}

Failed UnitTest1 TestMethod1 00:00:02.4153010 TestProject1  Test method TestProject1.UnitTest1.TestMethod1 threw exception:  Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the dependency failed, type = "Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter", name = "". Exception message is: The current build operation (build key Build Key[Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter, null]) failed: The parameter filters could not be resolved when attempting to call constructor Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter(System.Collections.Generic.ICollection`1[[Microsoft.Practices.EnterpriseLibrary.Logging.Filters.ILogFilter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]] filters, System.Collections.Generic.IDictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[Microsoft.Practices.EnterpriseLibrary.Logging.LogSource, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]] traceSources, Microsoft.Practices.EnterpriseLibrary.Logging.LogSource allEventsTraceSource, Microsoft.Practices.EnterpriseLibrary.Logging.LogSource notProcessedTraceSource, Microsoft.Practices.EnterpriseLibrary.Logging.LogSource errorsTraceSource, System.String defaultCategory, System.Boolean tracingEnabled, System.Boolean logWarningsWhenNoCategoriesMatch, System.Boolean revertImpersonation). (Strategy type BuildPlanStrategy, index 3) --->  Microsoft.Practices.ObjectBuilder2.BuildFailedException: The current build operation (build key Build Key[Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter, null]) failed: The parameter filters could not be resolved when attempting to call constructor Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter(System.Collections.Generic.ICollection`1[[Microsoft.Practices.EnterpriseLibrary.Logging.Filters.ILogFilter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]] filters, System.Collections.Generic.IDictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[Microsoft.Practices.EnterpriseLibrary.Logging.LogSource, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]] traceSources, Microsoft.Practices.EnterpriseLibrary.Logging.LogSource allEventsTraceSource, Microsoft.Practices.EnterpriseLibrary.Logging.LogSource notProcessedTraceSource, Microsoft.Practices.EnterpriseLibrary.Logging.LogSource errorsTraceSource, System.String defaultCategory, System.Boolean tracingEnabled, System.Boolean logWarningsWhenNoCategoriesMatch, System.Boolean revertImpersonation). (Strategy type BuildPlanStrategy, index 3) --->  System.InvalidOperationException: The parameter filters could not be resolved when attempting to call constructor Microsoft.Practices.EnterpriseLibrary.Logging.LogWriter(System.Collections.Generic.ICollection`1[[Microsoft.Practices.EnterpriseLibrary.Logging.Filters.ILogFilter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]] filters, System.Collections.Generic.IDictionary`2[[System.String, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[Microsoft.Practices.EnterpriseLibrary.Logging.LogSource, Microsoft.Practices.EnterpriseLibrary.Logging, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35]] traceSources, Microsoft.Practices.EnterpriseLibrary.Logging.LogSource allEventsTraceSource, Microsoft.Practices.EnterpriseLibrary.Logging.LogSource notProcessedTraceSource, Microsoft.Practices.EnterpriseLibrary.Logging.LogSource errorsTraceSource, System.String defaultCategory, System.Boolean tracingEnabled, System.Boolean logWarningsWhenNoCategoriesMatch, System.Boolean revertImpersonation). --->  Microsoft.Practices.ObjectBuilder2.BuildFailedException: The current build operation (build key Build Key[System.Collections.Generic.ICollection`1[Microsoft.Practices.EnterpriseLibrary.Logging.Filters.ILogFilter], null]) failed: The current type, System.Collections.Generic.ICollection`1[Microsoft.Practices.EnterpriseLibrary.Logging.Filters.ILogFilter], is an interface and cannot be constructed. Are you missing a type mapping? (Strategy type BuildPlanStrategy, index 3) --->  System.InvalidOperationException: The current type, System.Collections.Generic.ICollection`1[Microsoft.Practices.EnterpriseLibrary.Logging.Filters.ILogFilter], is an interface and cannot be constructed. Are you missing a type mapping?. 

May 20, 2009 at 8:42 AM

So you copied the config from the quickstart, right?  Just to make sure, could you check that the config you copied still has the entry for the LoggingBlockExtension in the <types> section?  'Coz I already tried this code in a Test project and I'm still able to resolve an instance of LogWriter successfully.

 

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.

entlib.support@avanade.com

 

May 20, 2009 at 9:02 AM
Edited May 20, 2009 at 9:04 AM

Yep. (I assume you mean in the extensions section for the container).

Further, when I step over this line in the debugger:
unityConfigurationSection.Containers["loggingContainer"].Configure(unityContainer);

I can see the extensions, ie:
non-public members:
_extensions:
+  [0] {Microsoft.Practices.Unity.UnityDefaultBehaviorExtension} Microsoft.Practices.Unity.UnityContainerExtension {Microsoft.Practices.Unity.UnityDefaultBehaviorExtension}
+  [1] {Microsoft.Practices.Unity.InjectedMembers} Microsoft.Practices.Unity.UnityContainerExtension {Microsoft.Practices.Unity.InjectedMembers}
+  [2] {Microsoft.Practices.Unity.UnityDefaultStrategiesExtension} Microsoft.Practices.Unity.UnityContainerExtension {Microsoft.Practices.Unity.UnityDefaultStrategiesExtension}
+  [3] {Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Unity.EnterpriseLibraryCoreExtension} Microsoft.Practices.Unity.UnityContainerExtension {Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Unity.EnterpriseLibraryCoreExtension}
+  [4] {Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.Unity.LoggingBlockExtension} Microsoft.Practices.Unity.UnityContainerExtension {Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.Unity.LoggingBlockExtension}

May 20, 2009 at 9:05 AM

Could you send me your test project? 

 

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.

entlib.support@avanade.com

May 20, 2009 at 9:23 AM

Emailed to enblib.support, Thanks!

May 20, 2009 at 9:30 AM

Hope you just mistyped entlib :), I haven't received it yet. 

 

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.

entlib.support@avanade.com

May 20, 2009 at 9:42 AM

It's in my sentbox hope it's gone through ok. I'll wait another 5 and send again if necessary.

May 20, 2009 at 10:00 AM

I'm looking at it now.  I'll let you know what I can find out.

 

 

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.

entlib.support@avanade.com

May 20, 2009 at 10:07 AM

Thanks Sarah. I've recreated this on 2 machines, hoping there's an easy fix/work-around, pretty hard to test components with dependencies on LogWriter and alike (TraceManager, ExceptionManager) without config. Have you seen the constructor on that thing, imagine setting it up for each test :)

May 20, 2009 at 10:32 AM

Ah, you don't have an app.config in your project containing your Logging section.  You might be expecting the container to get that from the configuration source you used for getting the unity section but that's not the case.  If you're going to look at the LoggingBlockExtension class, it gets the LoggingSettings from the current configuration source which always defaults to the SystemConfigurationSource (or the app.config/web.config of the project) if you didn't specified it.  Add an app.config in your test project and configure the Logging Application Block of you can set your default configuration source to point to the Copy of LoggingQuickstart.config.

 

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.

entlib.support@avanade.com

May 20, 2009 at 10:58 AM

Can you please send the ammended project back. I understand what you're saying but wasn't successful.

I added app.config to the test project, added a File Configuration Source which points to the original Logging Quick Start config.

Made the File Configuration Source the default config source, re-ran the test, and it failed at:

unityConfigurationSection.Containers["loggingContainer"].Configure(unityContainer);

I'm sure this is just my error...

May 20, 2009 at 11:12 AM
Edited May 20, 2009 at 11:23 AM

Sure, I'm sending it now.  Make sure that the configuration you're pointing to indeed contains the logging section.  In the project I sent, I just added a new App1.config, configure the logging section in it, and use it as the FileConfigurationSource.  I just checked your Copy of LoggingQuickstart.exe.config, it doesn't have a logging section in it.

 

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.

entlib.support@avanade.com

May 20, 2009 at 12:01 PM

Thanks Sarah, this is an excellent result for me! Thank you.

That's how I figured it would work, think my loggingConfiguration got corrupted somewhere along the line.