EntLib not working with Interop

Topics: Data Access Application Block
Oct 9, 2007 at 1:52 PM
Hi, I'm getting a weird message when I try to use EntLib 3.1 May 2007 with Interop.

I have a library in C# that access data trough EntLib (named Library1), this library is used by another library, also in C# that has been marked for COM Registration (named Library2) so I can expose it to COM.

I also have a Visual Basic 6 project that use Library2, but when I call in .NET this function trough COM code:

Database db = DatabaseFactory.CreateDatabase();

I get the following error:

The type initializer for 'Microsoft.Practices.EnterpriseLibrary.Data.DatabaseConfigurationView' threw an exception.

This ONLY happens with interop projects, I think, maybe, .NET Framework can not resolve where the Data (EntLib) assembly is located or maybe EntLib is looking in the wrong place for the app.config file.

Is there any work around, not using AssemblyResolve, to solve this problem?

Thank you!
Oct 11, 2007 at 1:34 PM
Hi,

The static initialization in DatabaseConfigurationView is really simple, just setting up instances of locally defined types, and it shouldn't be realated to config issues. Is there any way for you to catch the type initialization exception on the .net side?

Fernando
Oct 11, 2007 at 2:43 PM
Hola, thanks for your answer. I've managed to solve my problem by copying the EntLib assemblies and the app.config to the folder where the VB6 exe is located. In my home PC it works just fine, but, in my job I'm getting a new error: it says that it cannot find the Common dll from EntLib (referenced by Data dll of EntLib), maybe the problem is because I have installed EntLib Jan 2006 and May 2007?

For now I've replaced EntLib with my own Data Library by creating some sort of DataBase class, like EntLib; but the problem is still there when using Interop.

Again, thanks for your answer!
Dec 1, 2007 at 9:32 PM

I'm getting the same problem : The type initializer for 'Microsoft.Practices.EnterpriseLibrary.Data.DatabaseConfigurationView' threw an exception. at Microsoft.Practices.EnterpriseLibrary.Data.DatabaseConfigurationView..ctor(IConfigurationSource configurationSource)

I'm trying to use COM Interop to access a .NET Library from a Classic ASP Page using VBScript.

In my web app I have all the right settings in Web.config (at least ASP.NET pages work fine).

I have the following dlls in my Bin directory (among others):
Microsoft.Practices.EnterpriseLibrary.Caching.dll
Microsoft.Practices.EnterpriseLibrary.Common.dll
Microsoft.Practices.EnterpriseLibrary.Data.dll
Microsoft.Practices.ObjectBuilder.dll

Most of my work has been with .NET code for years... I'm very rusty now on ASP and COM.

My class has these attributes:
[ProgId("MyApp.Settings")]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[ComVisible(true)]
public class Settings
}

In the class library project settings I have "Register for COM Interop" on the Build tab of Properties checked.

.NET Reflector show this for the constructor:
public DatabaseConfigurationView(IConfigurationSource configurationSource)
{
this.configurationSource = configurationSource;
}

And all the various types for configurationSource (private IConfigurationSource configurationSource;) seem to be in dlls in the Bin directory or in the web.config (<add assembly="System.Configuration, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>).

Here's the code for IConfigurationSource:
public interface IConfigurationSource
{
// Methods
void Add(IConfigurationParameter saveParameter, string sectionName, ConfigurationSection configurationSection);
void AddSectionChangeHandler(string sectionName, ConfigurationChangedEventHandler handler);
ConfigurationSection GetSection(string sectionName);
void Remove(IConfigurationParameter removeParameter, string sectionName);
void RemoveSectionChangeHandler(string sectionName, ConfigurationChangedEventHandler handler);
}
All these types seem to be in either System.Configuration.dll or in Microsoft.Practices.EnterpriseLibrary.Common.dll.

Here is more of the Strack Trace:
The type initializer for 'Microsoft.Practices.EnterpriseLibrary.Data.DatabaseConfigurationView' threw an exception. at Microsoft.Practices.EnterpriseLibrary.Data.DatabaseConfigurationView..ctor(IConfigurationSource configurationSource) at Microsoft.Practices.EnterpriseLibrary.Data.DatabaseCustomFactory.CreateObject(IBuilderContext context, String name, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.ConfiguredObjectStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id) at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) at
Microsoft.Practices.ObjectBuilder.SingletonStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) at
Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.ConfigurationNameMappingStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id) at Microsoft.Practices.ObjectBuilder.BuilderBase`1.DoBuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies) at
Microsoft.Practices.ObjectBuilder.BuilderBase`1.BuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies) at Microsoft.Practices.ObjectBuilder.BuilderBase`1.BuildUp[TTypeToBuild](IReadWriteLocator locator, String idToBuild, Object existing, PolicyList[] transientPolicies) at
Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.EnterpriseLibraryFactory.BuildUp[T](IReadWriteLocator locator, String id, IConfigurationSource configurationSource) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.EnterpriseLibraryFactory.BuildUp[T](String id, IConfigurationSource configurationSource) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.NameTypeFactoryBase`1.Create(String name) at Microsoft.Practices.EnterpriseLibrary.Data.DatabaseFactory.CreateDatabase(String name) ...

Any ideas?
Dec 2, 2007 at 1:01 AM
OK... I think I have it narrowed down, but still need some help...
I don't think I mentioned that I'm using Enterprise Library 2.0 from Jan 2006.
It seems the issue is that the library can't find the web.config file.
I tried a trick from this post: http://dotnetslackers.com/ASP_NET/re-25499_External_configuration_files_in_Enterprise_Library_for_NET_Framework_2_0.aspx

Here's the method now:
public string GetIsConnectionValid()
{
try
{
FileConfigurationSource configSource = new FileConfigurationSource(@"C:\Inetpub\wwwroot\EntLibComInterop\web.config");
DatabaseProviderFactory dbFactory = new DatabaseProviderFactory(configSource);
Database db = dbFactory.Create("ConnectionString");
if (!ReferenceEquals(db, null))
return "yes";
else
return "no";
}
catch (Exception ex)
{
throw new Exception(ex.Message + " " + ex.StackTrace);
}
}

However, it seems like way back behind the scenes it doesn't actually honor the new Configuration Source... Or there's some other issue such as permissions (but most people seem to get permissions errors, and not this)

I get this:

The type initializer for 'Microsoft.Practices.EnterpriseLibrary.Data.DatabaseConfigurationView' threw an exception. at Microsoft.Practices.EnterpriseLibrary.Data.DatabaseConfigurationView..ctor(IConfigurationSource configurationSource) at Microsoft.Practices.EnterpriseLibrary.Data.DatabaseCustomFactory.CreateObject(IBuilderContext context, String name, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.ConfiguredObjectStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id) at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) at Microsoft.Practices.ObjectBuilder.SingletonStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.ConfigurationNameMappingStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id) at Microsoft.Practices.ObjectBuilder.BuilderBase`1.DoBuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies) at Microsoft.Practices.ObjectBuilder.BuilderBase`1.BuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies) at Microsoft.Practices.ObjectBuilder.BuilderBase`1.BuildUp[TTypeToBuild](IReadWriteLocator locator, String idToBuild, Object existing, PolicyList[] transientPolicies) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.EnterpriseLibraryFactory.BuildUp[T](IReadWriteLocator locator, String id, IConfigurationSource configurationSource) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.EnterpriseLibraryFactory.BuildUp[T](String id, IConfigurationSource configurationSource) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.NameTypeFactoryBase`1.Create(String name) at ClassLibrary1.Class1.GetIsConnectionValid() in C:\Public\EntLibComInterop Test\ClassLibrary1\Class1.cs:line 40


Dec 2, 2007 at 4:45 AM
Final post for the evening...
I suspect there's less energy around Ent Lib 2.0 and more around Microsoft Enterprise Library 3.1.
I've installed that on my machine.

References
All references point to the folder: C:\Program Files\Microsoft Enterprise Library 3.1 - May 2007\Bin
The web app has
Microsoft.Practices.EnterpriseLibrary.Common.dll
Microsoft.Practices.EnterpriseLibrary.Data.dll
Microsoft.Practices.ObjectBuilder.dll
and the Auto-refresh Path for all three points to:
C:\Program Files\Microsoft Enterprise Library 3.1 - May 2007\Bin

Class Library
Very short...
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;

namespace ClassLibrary1
{
[ProgId("ClassLibrary1.Class1")]
[ClassInterface(ClassInterfaceType.AutoDual)]
[ComVisible(true)]
public class Class1
{
public Class1()
{
}

public string GetIsConnectionValid()
{
try
{
FileConfigurationSource configSource = new FileConfigurationSource(@"C:\inetpub\wwwroot\EntLibComInterop\web.config");
DatabaseProviderFactory dbFactory = new DatabaseProviderFactory(configSource);
Database db = dbFactory.Create("UnitTests");
if (!ReferenceEquals(db, null))
return "yes";
else
return "no";
}
catch (Exception ex)
{
throw new Exception(ex.Message + " " + ex.StackTrace);
}
}

public string GetSimpleString()
{
return "This is just a simple string to show that COM Interop is working.";
}
}

}

Unit Test - runs just fine...
[TestMethod()]
public void GetIsConnectionValidTest()
{
Class1 target = new Class1();

string expected = "yes";
string actual;

actual = target.GetIsConnectionValid();

Assert.AreEqual(expected, actual, "ClassLibrary1.Class1.GetIsConnectionValid did not return the expected value.");
}

ASP Page
<%@ Language= "VBScript" %>
<html>
<head>
<title>Ent Lib 3.1 COM Interop Test</title>
</head>
<body>
<H1>Welcome to the Ent Lib 3.1 COM Interop Test Page</H1>
<%
' Make a call to COM to get some information.
Set class1Obj = Server.CreateObject("ClassLibrary1.Class1")
dim text1
text1 = ""
text1 = class1Obj.GetSimpleString()

' Now try the Ent Lib call
Dim text2
text2 = class1Obj.GetIsConnectionValid()
%>
Just a test page...<br />
The simple text is: <%=text1 %>
Is the connection string valid? <%=text2 %>
</body>
</html>

web.config
And finally, the contents of the smallest web.config I think I've even had...
<?xml version="1.0"?>
<configuration xmlns="http://schemas.microsoft.com/.NetConfiguration/v2.0">
<configSections>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"/>
</configSections>
<dataConfiguration defaultDatabase="UnitTests"/>
<connectionStrings>
<add name="UnitTests" connectionString="Data Source=.;Initial Catalog=UnitTestsDb;Persist Security Info=True;User ID=sa;Password=pwd" providerName="System.Data.SqlClient"/>
</connectionStrings>
<system.web>
<customErrors defaultRedirect="Error.aspx" mode="Off"/>
<compilation debug="true">
<assemblies>
<add assembly="System.Management, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>
<add assembly="System.Data.OracleClient, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Transactions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"/>
<add assembly="System.Configuration.Install, Version=2.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/></assemblies>
</compilation>
</system.web>
</configuration>

Result of displaying Test.asp?
ClassLibrary1 error '80131500'

An error occurred creating the configuration section handler for dataConfiguration: Could not load file or assembly 'Microsoft.Practices.EnterpriseLibrary.Data, Version=3.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' or one of its dependencies. The system cannot find the file specified. (C:\inetpub\wwwroot\EntLibComInterop\web.config line 4) at System.Configuration.BaseConfigurationRecord.FindAndEnsureFactoryRecord(String configKey, Boolean& isRootDeclaredHere) at System.Configuration.BaseConfigurationRecord.GetSectionRecursive(String configKey, Boolean getLkg, Boolean checkPermission, Boolean getRuntimeObject, Boolean requestIsHere, Object& result, Object& resultRuntimeObject) at System.Configuration.BaseConfigurationRecord.GetSection(String configKey, Boolean getLkg, Boolean checkPermission) at System.Configuration.Configuration.GetSection(String sectionName) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSourceImplementation.GetSection(String sectionName) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.FileConfigurationSource.GetSection(String sectionName) at Microsoft.Practices.EnterpriseLibrary.Data.DatabaseConfigurationView.get_DatabaseSettings() at Microsoft.Practices.EnterpriseLibrary.Data.DatabaseConfigurationView.GetProviderMapping(String name, String dbProviderName) at Microsoft.Practices.EnterpriseLibrary.Data.DatabaseCustomFactory.CreateObject(IBuilderContext context, String name, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.ConfiguredObjectStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id) at Microsoft.Practices.ObjectBuilder.SingletonStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) at Microsoft.Practices.ObjectBuilder.BuilderStrategy.BuildUp(IBuilderContext context, Type typeToBuild, Object existing, String idToBuild) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.ConfigurationNameMappingStrategy.BuildUp(IBuilderContext context, Type t, Object existing, String id) at Microsoft.Practices.ObjectBuilder.BuilderBase`1.DoBuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies) at Microsoft.Practices.ObjectBuilder.BuilderBase`1.BuildUp(IReadWriteLocator locator, Type typeToBuild, String idToBuild, Object existing, PolicyList[] transientPolicies) at Microsoft.Practices.ObjectBuilder.BuilderBase`1.BuildUp[TTypeToBuild](IReadWriteLocator locator, String idToBuild, Object existing, PolicyList[] transientPolicies) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.EnterpriseLibraryFactory.BuildUp[T](IReadWriteLocator locator, String id, IConfigurationSource configurationSource) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.EnterpriseLibraryFactory.BuildUp[T](String id, IConfigurationSource configurationSource) at Microsoft.Practices.EnterpriseLibrary.Common.Configuration.ObjectBuilder.NameTypeFactoryBase`1.Create(String name) at ClassLibrary1.Class1.GetIsConnectionValid() in C:\Users\Karl\Documents\Visual Studio 2005\Projects\EntLibComInterop\ClassLibrary1\Class1.cs:line 25

/EntLibComInterop/Test.asp, line 17
Dec 3, 2007 at 12:28 AM
OK... Working now...
Keys were:
  1. Must sign MY assembly
  2. Must be with the same key that Ent Lib is signed with (I promise that was the only change I made at one point and it started working)
  3. Must put Ent Lib libraries in the GAC (Something I try to avoid since we don't always get that luxury on the server) Simpler apps worked without this... I'm not sure why the more complex apps required this in the GAC.

I did drop back to Ent Lib 2.0 just so I didn't have to move everything else forward just yet.

I know I'm "talking to myself" here, but I hope this helps someone else at some point.

Cheers,
Karl
Jun 14, 2012 at 7:45 AM

Hi Karl

I know its been a while since you solved this problem but I am stuck with the exact same problem. 

I have all my assemblies with the same key and still it wouldn't work.

I am using Validation framework and the error is 
Could not load file Microsoft.Practices.EnterpriseLibrary.Validation

 

Any help is highly appreciated.

Thanks,

Rushi 

Jun 15, 2012 at 3:25 PM

When you say "I have all my assemblies signed with the same key" you mean that your assembly AND the Ent Lib assemblies are both signed with the same key?

And that you also put them in the GAC?