Enterprise Library in a Console Application

Topics: Data Access Application Block, Enterprise Library Core, Exception Handling Application Block, Logging Application Block
May 28, 2014 at 10:17 AM

We have recently upgraded from EL v4 to v6. We have a Website project and a Console Application project.

We use Data Access, Logging and Exception blocks, we placed the following code in the global.asax of our Website project when upgrading and EL works fine.
            DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory());
            var logWriterFactory = new LogWriterFactory();
            var logWriter = logWriterFactory.Create();
            var policyFactory = new ExceptionPolicyFactory();
            var exManager = policyFactory.CreateManager();
When trying to upgrade the console application project, I placed the code above into the "public static void Main" method of the console application but whenever trying to use a Database (by calling methods in a referenced dll) I get the following error:

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.

Do I need to do anything different to set the DatabaseFactory in a console application project?

May 28, 2014 at 1:03 PM
Edited Jun 5, 2014 at 5:09 AM
No, you shouldn't have to do anything different. For example, this works:
<?xml version="1.0"?>
    <add name="Logging" connectionString="data source=.\SQLEXPRESS;Integrated Security=SSPI;Database=Logging;User Instance=false;" providerName="System.Data.SqlClient"/>
    <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5"/>

static void Main(string[] args)
    DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory());

    Database database = DatabaseFactory.CreateDatabase("Logging");
Are you manually creating a separate AppDomain or anything else a little esoteric? It would help if you could post code/configuration or a sample project that reproduces the issue.

Randy Levy
Enterprise Library support engineer
Support How-to
May 28, 2014 at 1:31 PM
Hi Randy,

Yes good guess - the console application does create a separate AppDomain - which I guess is the cause of the issue as the EL objects are out of scope.

This may something you have no experience with - but I thought I would ask anyway - do you know if there is a way in which the Enterprise Library objects can be created and used (or somehow passed over) into a new AppDomain? The code is a little complex and project specific but see below the method being called by the console application:
         public T GetInstance<T> (string name, string folder,
            string assemblyName, string instanceTypeName, string configFile) where T : GS.Facade.IFacade
            AppDomainSetup appDomainSetup = new AppDomainSetup();
            appDomainSetup.ApplicationBase = folder;
            appDomainSetup.PrivateBinPath = folder;
            appDomainSetup.ConfigurationFile = configFile;

            AppDomainInitializer adi = new AppDomainInitializer(AppDomainInit);
            appDomainSetup.AppDomainInitializer = adi;

            if (!domainLoaded)
                appDomain = AppDomain.CreateDomain(DomainName, null, appDomainSetup);
            ObjectHandle oh = appDomain.CreateInstanceFrom(System.IO.Path.Combine(folder, assemblyName),
            domainLoaded = true;
            Object ob = oh.Unwrap();
            GS.Facade.IFacade calcFacade = (GS.Facade.IFacade)ob;
            Logger callBack = new Logger();
            callBack.FacadeName = name;
            calcFacade.CallBack = callBack;
            calcFacade.Name = name;
            return (T)calcFacade;
May 29, 2014 at 4:25 AM
In general, you are not going to be able to pass the Enterprise Library objects to/from a different AppDomain.

I'm assuming you are referencing/using a class which wraps Enterprise Library functionality. In that case, you can create a Bootstrapper class that you can instantiate in the new AppDomain and invoke a method to bootstrap the blocks. This could either be in the existing assembly or a new assembly:
    public class DatabaseBootstrapper : MarshalByRefObject
        public void Initialize()
            DatabaseFactory.SetDatabaseProviderFactory(new DatabaseProviderFactory());

Then you can create the AppDomain and bootstrap Enterprise Library and invoke the desired method:
AppDomainSetup domaininfo = new AppDomainSetup();
domaininfo.ConfigurationFile = AppDomain.CurrentDomain.SetupInformation.ConfigurationFile;

AppDomain domain = AppDomain.CreateDomain("MyDomain", null, domaininfo);
DatabaseBootstrapper bootstrapper = (DatabaseBootstrapper)


// Now that AppDomain is bootstrapped can create object (e.g. MyClass) in new AppDomain and invoke method that 
// does some work (e.g. DoDatabaseAction)
object obj = domain.CreateInstanceAndUnwrap(typeof(MyClass).Assembly.FullName, 

MyClass mc = (MyClass)obj;


If you want to "pass" Enterprise Library objects to/from the AppDomain you will have to wrap the Enterprise Library types in a MarshalByRefObject that exposes any functionality you require.

Randy Levy
Enterprise Library support engineer
Support How-to
Jun 3, 2014 at 9:02 AM
Great, thanks for the suggestions - very useful.