Search code examples
c#asp.net-mvcloggingexceptionenterprise-library

Migrate Enterprise Library 5 to 6


Trying to move from Enterprise Library 5.0 to 6.0, I ran into some troubles. Maybe this will help others.

Following configuration is an example for (silent) exception logging to database:

<configSections>
  <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging" requirePermission="true" />
  <section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling" requirePermission="true" />
</configSections>
<loggingConfiguration name="" tracingEnabled="true" defaultCategory="General">
  <listeners>
    <add name="Database Trace Listener" type="Microsoft.Practices.EnterpriseLibrary.Logging.Database.FormattedDatabaseTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging.Database"
         listenerDataType="Microsoft.Practices.EnterpriseLibrary.Logging.Database.Configuration.FormattedDatabaseTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging.Database"
         databaseInstanceName="LogContext" writeLogStoredProcName="WriteLog"
         addCategoryStoredProcName="AddCategory" formatter="Text Formatter" />
  </listeners>
  <formatters>
    <add type="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging"
         template="Timestamp: {timestamp}{newline}..."
         name="Text Formatter" />
  </formatters>
  <categorySources>
    <add switchValue="All" name="Exception">
      <listeners>
        <add name="Database Trace Listener" />
      </listeners>
    </add>
  </categorySources>
</loggingConfiguration>
<exceptionHandling>
  <exceptionPolicies>
    <add name="UiPolicy">
      <exceptionTypes>
        <add name="All Exceptions" type="System.Exception, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
             postHandlingAction="None">
          <exceptionHandlers>
            <add name="Logging Exception Handler" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging.LoggingExceptionHandler, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging"
                 logCategory="Exception" eventId="100" severity="Error" title="Enterprise Library Exception Handling"
                 formatterType="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.TextExceptionFormatter, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling"
                 priority="0" />
          </exceptionHandlers>
        </add>
      </exceptionTypes>
    </add>
  </exceptionPolicies>
</exceptionHandling>

I'm using following assemblies with version 5.0.414.0:

Microsoft.Practices.EnterpriseLibrary.ExceptionHandling Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Logging Microsoft.Practices.EnterpriseLibrary.Logging Microsoft.Practices.EnterpriseLibrary.Logging.Database

With Enterprise Library 5.0 using all this within a asp.net MVC app is as easy as:

// ...
catch (Exception ex)
{
    if (ExceptionPolicy.HandleException(ex, "UiPolicy")) throw;
    // do something else
}

After upgrading the assemblies to Enterprise Library 6.0, I get following exception message:

Must set an ExceptionManager in the ExceptionPolicy class using the SetExceptionManager method.

So, what to do?


Solution

  • Step by Step

    To get rid of this exception (credit to Randy's answer), one has to go with ExceptionManager, in my case via factory. I use this in global.asax' Application_Start() method:

    protected void Application_Start()
    {
        IConfigurationSource source = ConfigurationSourceFactory.Create();
    
        var exceptionPolicyFactory = new ExceptionPolicyFactory(source);
        var exceptionManager = exceptionPolicyFactory.CreateManager();
        ExceptionPolicy.SetExceptionManager(exceptionManager);
    }
    

    But with my handling and logging settings this was only half way. I now got the following exception at exceptionPolicyFactory.CreateManager()

    The LogWriter has not been set for the Logger static class. Set it invoking the Logger.SetLogWriter method.

    For this to go away I added

    var logwriterFactory = new LogWriterFactory(source);
    var logWriter = logwriterFactory.Create();
    Logger.SetLogWriter(logWriter);
    

    Now it said

    Database provider factory not set for the static DatabaseFactory. Set a provider factory invoking the DatabaseFactory.SetProviderFactory method or by specifying custom mappings by calling the DatabaseFactory.SetDatabases method.

    on logwriterFactory.Create(). So there was one more thing to add:

    DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory(source));
    

    Complete Solution

    All together my Application_Start() now is

    protected void Application_Start()
    {
        IConfigurationSource source = ConfigurationSourceFactory.Create();
        DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory(source));
    
        var logwriterFactory = new LogWriterFactory(source);
        var logWriter = logwriterFactory.Create();
        Logger.SetLogWriter(logWriter);
    
        var exceptionPolicyFactory = new ExceptionPolicyFactory(source);
        var exceptionManager = exceptionPolicyFactory.CreateManager();
        ExceptionPolicy.SetExceptionManager(exceptionManager);
    }
    

    while the configuration and the actual exception handling code stays the same:

    ExceptionPolicy.HandleException(exceptionToHandle, "UiPolicy");