Why is using the EntLib so hard?

Topics: Exception Handling Application Block
Jun 25, 2007 at 3:49 PM
I'm trying to use the EHAB, but I'm having no success whatever. I tried creating custom event handling classes for my ASP.NET app, but I kept getting useless errors. I am also trying to use the EntLib's wrap and replace handlers, but I keep getting errors like the following:

System.Configuration.ConfigurationErrorsException was unhandled
Message="The type Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ReplaceHandler from configuration could not be created. (C:\\Documents and Settings\\bking\\My Documents\\Visual Studio 2005\\Projects\\WPPTestHarness\\WindowsAppHarness\\bin\\Debug\\WindowsAppHarness.vshost.exe.config line 208)"
Source="System.Configuration"
BareMessage="The type Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ReplaceHandler from configuration could not be created."
Filename="C:\\Documents and Settings\\bking\\My Documents\\Visual Studio 2005\\Projects\\WPPTestHarness\\WindowsAppHarness\\bin\\Debug\\WindowsAppHarness.vshost.exe.config"
Line=208
StackTrace:
at System.Configuration.BaseConfigurationRecord.EvaluateOne(String[] keys, SectionInput input, Boolean isTrusted, FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult)
at System.Configuration.BaseConfigurationRecord.Evaluate(FactoryRecord factoryRecord, SectionRecord sectionRecord, Object parentResult, Boolean getLkg, Boolean getRuntimeObject, Object& result, Object& resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject)
at System.Configuration.BaseConfigurationRecord.GetSection(String configKey, Boolean getLkg, Boolean checkPermission)
at System.Configuration.BaseConfigurationRecord.GetSection(String configKey)
at System.Configuration.ClientConfigurationSystem.System.Configuration.Internal.IInternalConfigSystem.GetSection(String sectionName)
at System.Configuration.ConfigurationManager.GetSection(String sectionName)
at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.SystemConfigurationSourceImplementation.GetSection(String sectionName)
at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.SystemConfigurationSource.GetSection(String sectionName)
at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings.GetExceptionHandlingSettings(IConfigurationSource configurationSource)
at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionHandlingConfigurationView.get_ExceptionHandlingSettings()
at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionHandlingConfigurationView.GetExceptionPolicyData(String policyName)
at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicyCustomFactory.GetConfiguration(String id, IConfigurationSource configurationSource)
at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicyCustomFactory.CreateObject(IBuilderContext context, String name, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache)
at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.ConfiguredObjectStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id)
at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
at Microsoft.Practices.ObjectBuilder.SingletonStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild)
at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.ConfigurationNameMappingStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id)
at Microsoft.Practices.ObjectBuilder.BuilderBase`1.DoBuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies)
at Microsoft.Practices.ObjectBuilder.BuilderBase`1.BuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies)
at Microsoft.Practices.ObjectBuilder.BuilderBase`1.BuildUpTTypeToBuild(IReadWriteLocator locator, String idToBuild, Object existing, PolicyList[] transientPolicies)
at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.EnterpriseLibraryFactory.BuildUpT(IReadWriteLocator locator, String id, IConfigurationSource configurationSource)
at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.LocatorNameTypeFactoryBase`1.Create(String name)
at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicy.GetExceptionPolicy(Exception exception, String policyName)
at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicy.HandleException(Exception exceptionToHandle, String policyName)
at WindowsAppHarness.Form1.ThrowCmsException() in C:\Documents and Settings\bking\My Documents\Visual Studio 2005\Projects\WPPTestHarness\WindowsAppHarness\Form1.cs:line 82
at WindowsAppHarness.Form1..ctor() in C:\Documents and Settings\bking\My Documents\Visual Studio 2005\Projects\WPPTestHarness\WindowsAppHarness\Form1.cs:line 45
at WindowsAppHarness.Program.Main() in C:\Documents and Settings\bking\My Documents\Visual Studio 2005\Projects\WPPTestHarness\WindowsAppHarness\Program.cs:line 17
at System.AppDomain.nExecuteAssembly(Assembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()

Here's the section of the config file the EntLib is complaining about:

<add type="ADC.ContentManagement.InvalidCmsPathException" postHandlingAction="ThrowNewException" name="InvalidCmsPathException">
<exceptionHandlers>
<add exceptionMessage="Please check inner exception exception for more detailed explanation."
name="ContentManagementExceptionHandler"
type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ReplaceHandler"
wrapExceptionType="ADC.ContentManagement.CmsProviderException">
</add>
</exceptionHandlers>
</add>

I'm hoping that there's just a simple mistake in what I'm attempting, but that's not likely given my experience with the Ent LIb.

<rant>
Honestly, given the steep learning curve, lack of documentation, and lack of support, the Ent Lib just isn't worth the effort.
</rant>
Jun 25, 2007 at 6:15 PM
Hi Byron,

I'm sorry you're facing these issues. Have you tried the EH quickstarts? They should work as a good introduction to the exception handlig features.

The error you pasted refers to the inability to deserialize configuration, but you seem to be launching your test app from the IDE, so it is unlikely this is a deployment problem. Can you please try running the quickstarts and unit tests to verify they do work on your dev machine? Btw, which version of the enterprise library are you using?

Fernando

Jun 26, 2007 at 2:29 AM
Fernando,

Thanks for the reply. I have indeed tried the QuickStarts . They run fine on my machine. I am using EntLib 2.0. I agree with you that the QuickStarts are good intros, but I will submit that that is only the case when everything already works. For some reason, no matter how I create a custom exception class, the EH either cannot resolve it or cannot "create" it. If I replace the wrapExceptionType with something like System.Exception, I can get it working, but that's not what I want. The EntLib configuration tool can successfully load my assembly with the custom exception class that derives from System.Exception, so why does the EHAB have trouble resolving the exception class from an assembly it knows about? Any help is greatly appreciated.


fsimonazzi wrote:
Hi Byron,

I'm sorry you're facing these issues. Have you tried the EH quickstarts? They should work as a good introduction to the exception handlig features.

The error you pasted refers to the inability to deserialize configuration, but you seem to be launching your test app from the IDE, so it is unlikely this is a deployment problem. Can you please try running the quickstarts and unit tests to verify they do work on your dev machine? Btw, which version of the enterprise library are you using?

Fernando



Jun 26, 2007 at 4:30 PM
Hi Byron,

The error is not about creating the exception but creating the object representing the configuration information. In v2, configuration properties representing types were converted from strings when deserializing, so failure to load the type caused a configuration deserialization failure, while in v3 types are only resolved when they are actually used. However, the error you'd get in this case would be specific to this situation and not the one you're getting.

The error you're getting (which I agree is not very expressive) reflects the inability to load a type based on a name. In the configuration snippet you pasted, you're missing the assembly name on
type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ReplaceHandler", and that is very likely causing the load error; this error should happen regardless of the value set for the wrapExceptionType. I missed it on your first post.

This configuration error can only be caused by manual modification of the configuration file so editing the file with the configuration tool should not cause it. Can you test if you still get an error after editing the file with your desired configuration, and if this error is still the same "type could not be created" error?

Hope this helps,
Fernando


byronfromwes92 wrote:
Fernando,

Thanks for the reply. I have indeed tried the QuickStarts . They run fine on my machine. I am using EntLib 2.0. I agree with you that the QuickStarts are good intros, but I will submit that that is only the case when everything already works. For some reason, no matter how I create a custom exception class, the EH either cannot resolve it or cannot "create" it. If I replace the wrapExceptionType with something like System.Exception, I can get it working, but that's not what I want. The EntLib configuration tool can successfully load my assembly with the custom exception class that derives from System.Exception, so why does the EHAB have trouble resolving the exception class from an assembly it knows about? Any help is greatly appreciated.


fsimonazzi wrote:
Hi Byron,

I'm sorry you're facing these issues. Have you tried the EH quickstarts? They should work as a good introduction to the exception handlig features.

The error you pasted refers to the inability to deserialize configuration, but you seem to be launching your test app from the IDE, so it is unlikely this is a deployment problem. Can you please try running the quickstarts and unit tests to verify they do work on your dev machine? Btw, which version of the enterprise library are you using?

Fernando




Jun 26, 2007 at 7:40 PM
Fernando,

Thanks again for the reply. Your explanation makes sense. I stepped through the EntLib source code and observed exactly what you described. As it turns out, what made the difference in the end was how I registered the assembly containing my custom exception class. When I replaced the .dll reference in my app with a reference to the project housing the .dll, the error went away and I was then able to get the code to run as expected.

Perhaps, I don't understand VS2005 as well as I should , but does that make sense to you?

Regards,

byronfromwes92
Jun 26, 2007 at 8:24 PM
Byron,

I'm happy you could get this working. Regarding your question, what do you mean by "registered the assembly"? Is it adding a reference in your project? In any case, the behavior of the configuration tool should not be affected by this registration, as it only deals with assemblies. Changing the assembly reference in VS might affect whether the assembly is copied to the output folder of your app and that might have an effect at runtime (i.e. your custom exception type cannot be found) but that wouldn't cause the error you're describing.

Having a reference to the project or to the assembly should make no difference in this situation. If you would rather have a reference to the dll instead of the project (btw, by "housing the dell" you mean the project of which the dll is its output) then please try changing the reference from your working version. It should work.

Fernando
Jun 28, 2007 at 2:33 PM
Fernando,

As it turns out, the code only works when I specify a project reference. If I browse to a .dll, I get the error I reported previously. Thanks again for the help.

Cheers,

byronfromwes92
Jul 11, 2007 at 8:53 PM
By any chance are you signing your project with your own key. If yes then you have to use the app blocks that are signed with your own key too. That is probably why when you reference the project it works.

RDhillon