The type Database cannot be constructed. You must configure the container to supply this value

Topics: Data Access Application Block, Enterprise Library Core
Dec 5, 2012 at 9:28 PM

Hello All,

I recently upgraded my Windows Forms VB projects from CLR 2.0 to CLR 4.0. With this change, we decided to move to the latest MS Enterprise Library 5, update 1 (CLR 4.0) from Enterprise Library 2 (CLR 2.0). On our development and internal test machines, everything works great when we attempt to create a EnterpriseLibrary.Data.Database object. Once we installed the same apps onto our client's computers, we started to get errors in which the database connection could not be established. 

Here is the errors that I log using my custom error logger:

DATABASE CONNECTION FAILED. REASON: Activation error occured while trying to get instance of type Database, key "MyConnection"

EXCEPTION INFORMATION: THROWN EXCEPTION: Microsoft.Practices.ServiceLocation.dll.GetInstanceMSG: Activation error occured while trying to get instance of type Database, key "MyConnection"

INNER EXCEPTION: MSG: Resolution of the dependency failed, type = "Microsoft.Practices.EnterpriseLibrary.Data.Database", name = "MyConnection".Exception occurred while: while resolving.Exception is: InvalidOperationException - The type Database cannot be constructed. You must configure the container to supply this value.

Here is my actual configuration file with the connection information modified:

<?xml version="1.0"?>
<configuration>
  <configSections>
        <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data" />
    </configSections>
  <dataConfiguration defaultDatabase="MyConnection"/>
  <connectionStrings>
    <clear />
    <add name="MyConnection" connectionString="Database=DB1;Server=SERVER1;UID=USER1;PWD=PASSWORD1;Connect Timeout=15;" providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

 

<!--?xml version="1.0"?-->The configuration file was simplified to remove version, culture and publickeytoken references 
since our computers may need to toggle between the Enterprise Library 2.0 and Enterprise Library 5.0 components at different times.

Here is the call that we make to create the database object

Dim objDB As Database = DatabaseFactory.CreateDatabase("MyConnection")
The MyConnection string is indeed valid since I confirmed the connection string works everywhere else.
I can copy the exact same app .exe.config file to various development and test workstations and
everything works as expected. In addition, I have tried adding various sections and fully qualifying 
the assemblies using a combination of some or all of the following config file sections:
<configSections>
	<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.505.0, Culture=neutral" />
</configSections>

<system.data>
  <DbProviderFactories>
    <remove invariant="System.Data.SqlClient" />
    <add name="SqlClient Data Provider"
     invariant="System.Data.SqlClient" 
     description=".Net Framework Data Provider for SqlServer" 
     type="System.Data.SqlClient.SqlClientFactory, System.Data"
    />
  </DbProviderFactories>
</system.data>

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Data" fullName="Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.505.0, Culture=neutral"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Common" fullName="Microsoft.Practices.EnterpriseLibrary.Common, Version=5.0.505.0, Culture=neutral"/>
    <qualifyAssembly partialName="Microsoft.Practices.EnterpriseLibrary.Logging" fullName="Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.505.0, Culture=neutral"/>
    <qualifyAssembly partialName="Microsoft.Practices.ServiceLocation" fullName="Microsoft.Practices.ServiceLocation, Version=1.0.0.0, Culture=neutral, publicKeyToken=31BF3856AD364E35"/>
    <qualifyAssembly partialName="Microsoft.Practices.Unity" fullName="Microsoft.Practices.Unity, Version=2.1.505.0, Culture=neutral, publicKeyToken=31BF3856AD364E35"/>
    <qualifyAssembly partialName="Microsoft.Practices.Unity.Configuration" fullName="Microsoft.Practices.Unity.Configuration, Version=2.1.505.0, Culture=neutral, publicKeyToken=31BF3856AD364E35"/>
    <qualifyAssembly partialName="Microsoft.Practices.Unity.Interception" fullName="Microsoft.Practices.Unity.Interception, Version=2.1.505.0, Culture=neutral, publicKeyToken=31BF3856AD364E35"/>
    <qualifyAssembly partialName="Microsoft.Practices.Unity.Interception.Configuration" fullName="Microsoft.Practices.Unity.Interception.Configuration, Version=2.1.505.0, Culture=neutral, publicKeyToken=31BF3856AD364E35"/>
  </assemblyBinding>
</runtime>
Even with all of this information, I can get the apps to run on my development and test machines.
However, the client machines always fail.

The client machines are a mix of Windows XP SP3 and Windows 7 machines, with a majority of them being Wiondows 7.
They are locked down very heavily so the user is limited in what they can do.
When I re-install the previous apps that run CLR 2.0 and Enterprise Library 2.0, the apps run perfectly fine against the same simplified .exe.config file.
However, the CLR 4.0 and Enterprise Library 5 update 1 apps fail with the noted errors.

I am at the point that this issue must have something to do with the client machine and how they are locked down.
I suspect that the Enterprise Library 5 components cannot read my config file and somehow fails to read the MyConnection connection string.
Does anyone have an idea where I can look? I have scoured this forum and the internet for answers but I have yet to find the right solution.

Thanks in advance,
Don
Dec 6, 2012 at 5:38 PM

That's a tricky issue.  Almost certainly something to do with the configuration/security.  The problem is how to troubleshoot it.  The best situation would be to have access to a machine.

My first thought was something with the DbProviderFactories but it sounds like you have tried to add them (in case they don't exist/can't be read).  I'm still curious if you can get the listing.  You can do it with powershell (or a .NET program):

[System.Data.Common.DbProviderFactories]::GetFactoryClasses() | % { $_.InvariantName }

I also wonder if the InnerException itself has an InnerException?

Another thing to try would be to see if any kind of data access is possible.  I.e. can you open a database connection using straight ADO.NET?  That might give some more information.

--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com