Enterprise Library 6.0 in Web Service - Where to instantiate?

Topics: Data Access Application Block, Exception Handling Application Block, Logging Application Block
Mar 10 at 1:13 AM
Where do I put the statements that instantiate the Enterprise Library 6.0 factories when used with a web service? Should they go in the Class constructor, keeping the factories with class level scope, or do I include all that in each web service function keeping all the scopes local?

I have an old web service that I'm upgrading from .NET 2.0 and Enterprise Library 2.0 to .NET 4.6.1 and Enterprise Library 6.0. We still use the web.config for declaring the libraries, and I have added code required to make it work with 6.0.

The initial approach has been to have the factories configured in the constructor.

The first call to the web service works fine, but on subsequent calls I get errors on Logger.SetLogWriter and DatabaseFactory.SetDatabaseProviderFactory statements ("The LogWriter is already set." and "The static DatabaseFactory already has a database provider factory or custom methods set.").

I know I can include throwIfSet:=false, but found a mention that this may cause some unwanted behavior.

Also - do I need to add any Finalize logic for these?

I have the following:

<WebService(Namespace:="MyWebService")>
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)>
Public Class MyWebServiceInterface
    Inherits System.Web.Services.WebService


    ' ELib 6.0
    Dim config As IConfigurationSource = ConfigurationSourceFactory.Create()
    Dim factory As ExceptionPolicyFactory = New ExceptionPolicyFactory(config)
    Dim logFactory As LogWriterFactory = New LogWriterFactory(config)
    Dim dbfactory As DatabaseProviderFactory = New DatabaseProviderFactory()

``
Public Sub New()

    Try
        ' ELib 6.0
       Logger.SetLogWriter(logFactory.Create(), True)
        Dim exMgr As ExceptionManager = factory.CreateManager()
        ExceptionPolicy.SetExceptionManager(exMgr, True)
    Catch ex As Exception
        ' Simply Ignore
        ' We cannot log or handle Exceptions until LogWriter and ExceptionPolicy is set up...!
    End Try
    Try
        DatabaseFactory.SetDatabaseProviderFactory(New DatabaseProviderFactory(), True)
        ...
    Catch ex As Exception
        'Log exceptions.
        ExceptionPolicy.HandleException(ex, "Log Only Policy")
    End Try
```
Mar 10 at 2:09 AM
Edited Mar 10 at 2:10 AM
Are you running IIS in Classic Mode? If so then the standard way of performing a one time initialization at application startup is to use the Application_Start method of Global.asax. See ASP.NET Application Life Cycle Overview for IIS 5.0 and 6.0 for more information.

If you aren't running in Classic Mode, then you would need to perform a one time initialization to load the configuration before using any of the EntLib objects/methods. One way to do this would be to create a common base class that extends WebService and have that base class perform the initialization in a static (shared) constructor. So your code would look something like this:
<WebService(Namespace:="MyWebService")>
<WebServiceBinding(ConformsTo:=WsiProfiles.BasicProfile1_1)>
Public Class MyWebServiceInterface
    Inherits MyWebService

End Class

Public Class MyWebService
    Inherits System.Web.Services.WebService

    Shared Sub New()

        Try
            ' ELib 6.0
            Dim config As IConfigurationSource = ConfigurationSourceFactory.Create()
            Dim factory As ExceptionPolicyFactory = New ExceptionPolicyFactory(config)
            Dim logFactory As LogWriterFactory = New LogWriterFactory(config)
            Dim dbfactory As DatabaseProviderFactory = New DatabaseProviderFactory()

            Logger.SetLogWriter(logFactory.Create(), True)
            Dim exMgr As ExceptionManager = factory.CreateManager()
            ExceptionPolicy.SetExceptionManager(exMgr, True)
        Catch ex As Exception
            ' Simply Ignore
            ' We cannot log or handle Exceptions until LogWriter and ExceptionPolicy is set up...!
        End Try

        Try
            DatabaseFactory.SetDatabaseProviderFactory(New DatabaseProviderFactory(), True)
        Catch ex As Exception
            'Log exceptions.
            ExceptionPolicy.HandleException(ex, "Log Only Policy")
        End Try

    End Sub

End Class

Finally, since you mention .NET 4.6.1, you could use some sort startup class such as owin startup or webactivatorex.

Also - do I need to add any Finalize logic for these?

No, you don't have to manage the lifetime of the EntLib objects.
Marked as answer by TBQ on 3/10/2016 at 7:34 AM
Mar 10 at 3:34 PM
Thanks! That did the trick.

We are targeting Windows 2012 R2, so either IIS 8.5 or newer, and we do not plan to run in Classic mode.