Problem referencing entlib from BHO/COM dll: Object reference not set to an instance of an object

Topics: Exception Handling Application Block, General discussion
Dec 10, 2008 at 3:55 PM
Edited Dec 10, 2008 at 4:01 PM
I'm trying to use the Exception Handling AB to log exceptions to my application event log. This works fine for my projects that compile to executables but for the ones that compile to dlls and are loaded as Browser Helper Objects (BHOs) or called from COM objects I get an exception 'Object reference not set to an instance of an object' when I hit the line:

                    ExceptionPolicy.HandleException(ex, "Global Policy");

The stack trace is
   at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicy.GetExceptionPolicy(Exception exception, String policyName, ExceptionPolicyFactory factory)
   at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicy.HandleException(Exception exceptionToHandle, String policyName, ExceptionPolicyFactory policyFactory)
   at Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.ExceptionPolicy.HandleException(Exception exceptionToHandle, String policyName)
   at <the line shown above>

The same config file works fine in my exe projects so I assume it is correct. I guess the problem is that it's trying to create the appropriate objects but the necessary assemblies aren't or can't be loaded. I have the following references in my project (I will be changing the config to log to database once it's working logging to event log, hence the data references):

When I step through my code in the debugger it shows that only the dlls for the first 3 assemblies above are loaded, which i'm guessing is part of the problem? In my bin\debug\ directory all 6 dlls were there when referencing the dlls directly. None are there when referencing the GAC.

I've tried referencing copies of the strong-named dlls that ship with entlib and also tried referencing the assemblies in the GAC, both with the same result.

If I add the entlib projects to my sln to try to step into the ExceptionPolicy.HandleException() call I get problems because they're not strong-named...

Any suggestions as to what I'm doing wrong or how I can diagnose what is going wrong?

The config file I'm using is:

    <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    <section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
  <loggingConfiguration name="Logging Application Block" tracingEnabled="true"
    defaultCategory="General" logWarningsWhenNoCategoriesMatch="true">
      <add source="Enterprise Library Logging" formatter="Text Formatter"
        log="Application" machineName="" listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
        traceOutputOptions="Callstack" type="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
        name="Formatted EventLog TraceListener" />
      <add template="Timestamp: {timestamp}&#xD;&#xA;Message: {message}&#xD;&#xA;Category: {category}&#xD;&#xA;Priority: {priority}&#xD;&#xA;EventId: {eventid}&#xD;&#xA;Severity: {severity}&#xD;&#xA;Title:{title}&#xD;&#xA;Machine: {machine}&#xD;&#xA;Application Domain: {appDomain}&#xD;&#xA;Process Id: {processId}&#xD;&#xA;Process Name: {processName}&#xD;&#xA;Win32 Thread Id: {win32ThreadId}&#xD;&#xA;Thread Name: {threadName}&#xD;&#xA;Extended Properties: {dictionary({key} - {value}&#xD;&#xA;)}"
        type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
        name="Text Formatter" />
      <add categoryFilterMode="AllowAllExceptDenied" type="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.CategoryFilter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
        name="Category Filter" />
      <add switchValue="All" name="General">
          <add name="Formatted EventLog TraceListener" />
      <allEvents switchValue="All" name="All Events" />
      <notProcessed switchValue="All" name="Unprocessed Category" />
      <errors switchValue="All" name="Logging Errors &amp; Warnings">
          <add name="Formatted EventLog TraceListener" />
      <add name="Global Policy">
          <add type="System.Exception, mscorlib, Version=, Culture=neutral, PublicKeyToken=b77a5c561934e089"
            postHandlingAction="None" name="Exception">
              <add logCategory="General" eventId="100" severity="Error" title="Enterprise Library Exception Handling"
                formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                priority="0" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging, Version=, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
                name="Logging Handler" />

Any suggestions greatly (!!!) appreciated.

I'm using Enterprise Library 3.1 with Visual Studio 2005.


- Rory
Dec 11, 2008 at 4:39 AM
Just to clarify, you should be placing your configuration files in executables.  For the ones that compiles in dll, your configuration file should still be in the executable which calls the class in the assembly.

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc.
Dec 11, 2008 at 11:45 AM
You mean put the config file for the dll in the same folder as the executable? That seems pretty odd: if I didn't build the exe why would i put a config file in its folder? In some cases the exe is iexplore.exe, surely I don't have to put my config file in C:\Program Files\Internet Explorer\. In the case of creating COM-visible .net assemblies, I don't know which executable will be calling my dll so I can't know where to put the files.
Dec 11, 2008 at 2:40 PM
Edited Dec 11, 2008 at 2:46 PM
The thing is, configuration files belong to applications and not to dlls.  You can read through this post for more details...

You can specify through code where to pick up the configuration file by using an IConfigurationSource -

Sarah Urmeneta
Global Technology & Solutions
Avanade, Inc. 
Dec 11, 2008 at 6:14 PM
Edited Dec 12, 2008 at 1:44 AM
The solution lies here in the examples under 'using several configuration sources'... I've put together an example in this other post.

The problem with the IConfigurationSource example linked to is that it suggests using the app config file to point to the other configuration file. You're right that you can do it in code instead though, which is what I've now done.

thanks for the suggestions!

- Rory