Jun 8, 2010 at 9:36 AM
Edited Jun 8, 2010 at 9:38 AM
|
Hello.
Following a recent upgrade from version 4.1 to 5.0 of the Enterprise Library, once we access some web form we get the following error:
The type Database cannot be constructed. You must configure the container to supply this value.
Description:
An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details:
System.InvalidOperationException: The type Database cannot be constructed. You must configure the container to supply this value.
Source Error:
|
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace
below.
|
Stack Trace:
|
[InvalidOperationException: The type Database cannot be constructed. You must configure the container to supply this value.]
Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.GuardTypeIsNonPrimitive(IBuilderContext context, SelectedConstructor selectedConstructor) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\DynamicMethod\Creation\DynamicMethodConstructorStrategy.cs:289
Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy.PreBuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\DynamicMethod\Creation\DynamicMethodConstructorStrategy.cs:71
Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\StrategyChain.cs:110
Microsoft.Practices.ObjectBuilder2.DynamicMethodBuildPlanCreatorPolicy.CreatePlan(IBuilderContext context, NamedTypeBuildKey buildKey) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\DynamicMethod\DynamicMethodBuildPlanCreatorPolicy.cs:48
Microsoft.Practices.ObjectBuilder2.BuildPlanStrategy.PreBuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\BuildPlan\BuildPlanStrategy.cs:37
Microsoft.Practices.ObjectBuilder2.StrategyChain.ExecuteBuildUp(IBuilderContext context) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\ObjectBuilder\Strategies\StrategyChain.cs:110
Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs:511
[ResolutionFailedException: Resolution of the dependency failed, type = "Microsoft.Practices.EnterpriseLibrary.Data.Database", name = "(none)".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The type Database cannot be constructed. You must configure the container to supply this value.
-----------------------------------------------
At the time of the exception, the container was:
Resolving Microsoft.Practices.EnterpriseLibrary.Data.Database,(none)
]
Microsoft.Practices.Unity.UnityContainer.DoBuildUp(Type t, Object existing, String name, IEnumerable`1 resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs:515
Microsoft.Practices.Unity.UnityContainer.Resolve(Type t, String name, ResolverOverride[] resolverOverrides) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityContainer.cs:173
Microsoft.Practices.Unity.UnityServiceLocator.DoGetInstance(Type serviceType, String key) in e:\Builds\Unity\UnityTemp\Compile\Unity\Unity\Src\UnityServiceLocator.cs:64
Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) in c:\Home\Chris\Projects\CommonServiceLocator\main\Microsoft.Practices.ServiceLocation\ServiceLocatorImplBase.cs:49
[ActivationException: Activation error occured while trying to get instance of type Database, key ""]
Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(Type serviceType, String key) in c:\Home\Chris\Projects\CommonServiceLocator\main\Microsoft.Practices.ServiceLocation\ServiceLocatorImplBase.cs:53
Microsoft.Practices.ServiceLocation.ServiceLocatorImplBase.GetInstance(String key) in c:\Home\Chris\Projects\CommonServiceLocator\main\Microsoft.Practices.ServiceLocation\ServiceLocatorImplBase.cs:103
Microsoft.Practices.EnterpriseLibrary.Data.DatabaseFactory.InnerCreateDatabase(String name) in e:\Builds\EntLib\Latest\Source\Blocks\Data\Src\Data\DatabaseFactory.cs:82
clsCommon.GetDropDownList(String tablename, String field1, String field2, String fieldWhere, String val, String OtherTable, String ForeignKeyId, String OtherId) +39
UserPages_Products.BindUnitDropDown() +166
UserPages_Products.Page_Load(Object sender, EventArgs e) +24
System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, Object o, Object t, EventArgs e) +14
System.Web.Util.CalliEventHandlerDelegateProxy.Callback(Object sender, EventArgs e) +46
System.Web.UI.Control.OnLoad(EventArgs e) +83
clsBasePage.OnLoad(EventArgs e) +168
System.Web.UI.Control.LoadRecursive() +120
System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +3958
|
Version Information: Microsoft .NET Framework Version:4.0.30319; ASP.NET Version:4.0.30319.1
Following is also our web.config:
<?
xml
version="1.0"
<
configuration
>
<
configSections
>
<
section
name="dataConfiguration"
type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.414.0,
Culture=neutral, PublicKeyToken=31bf3856ad364e35"
/>
</
configSections
>
<
appSettings
>
<
add
key="ReportService.ReportService2005"
value="http://192.168.123.10/ServicesReportServer/ReportService2005.asmx"
/>
</
appSettings
>
<
connectionStrings
>
<
add
name="ConfigConnectionString"
connectionString="server=ABC_Server;database=SomeDB;User ID=SomeUser;Password=SomePassword"
providerName="System.Data.SqlClient"
/>
</
connectionStrings
>
<
system.web
>
<
compilation
debug="true"
targetFramework="4.0"
>
<
assemblies
>
<
add
assembly="Microsoft.VisualBasic, Version=10.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"
/>
<
add
assembly="System.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"
/>
<
add
assembly="System.Data.Entity, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"
/>
<
add
assembly="System.Data.Entity.Design, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B77A5C561934E089"
/>
<
add
assembly="Accessibility, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"
/>
<
add
assembly="Microsoft.ReportViewer.WinForms, Version=9.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"
/>
<
add
assembly="Microsoft.ReportViewer.Common, Version=9.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"
/>
<
add
assembly="Microsoft.ReportViewer.WebForms, Version=9.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/></assemblies
>
<
buildProviders
>
<
add
extension=".rdlc"
type="Microsoft.Reporting.RdlBuildProvider, Microsoft.ReportViewer.Common, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
/>
<
add
extension=".edmx"
type="System.Data.Entity.Design.AspNet.EntityDesignerBuildProvider"
/>
</
buildProviders
>
</
compilation
>
<
identity
impersonate="true"
/>
<
authentication
mode="Forms"
>
<
forms
defaultUrl="~/UserPages/Default.aspx"
loginUrl="~/Login/Default.aspx"></forms
>
</
authentication
>
<
authorization
>
<
deny
users="?"
/>
</
authorization
>
<
sessionState
mode="InProc"></sessionState
>
<
customErrors
mode="Off"></customErrors
>
<
pages
validateRequest="false"
enableEventValidation="false"
styleSheetTheme="Default"
controlRenderingCompatibilityVersion="3.5"
clientIDMode="AutoID"
>
</
pages
>
<
httpHandlers
>
<
add
path="Reserved.ReportViewerWebControl.axd"
verb="*"
type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
validate="false"
/>
</
httpHandlers
>
</
system.web
>
<
system.webServer
>
<
validation
validateIntegratedModeConfiguration="false"
/>
<
handlers
>
<
add
name="Reserved.ReportViewerWebControl.axd"
path="Reserved.ReportViewerWebControl.axd"
verb="*"
type="Microsoft.Reporting.WebForms.HttpHandler, Microsoft.ReportViewer.WebForms, Version=9.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"
resourceType="Unspecified"
preCondition="integratedMode"
/>
</
handlers
>
</
system.webServer
>
<
runtime
>
<
assemblyBinding
xmlns="urn:schemas-microsoft-com:asm.v1"
>
<
dependentAssembly
>
<
assemblyIdentity
name="Microsoft.ReportViewer.WebForms"
publicKeyToken="b03f5f7f11d50a3a"
/>
<
bindingRedirect
oldVersion="8.0.0.0-8.1.0.0"
newVersion="9.0.0.0"
/>
</
dependentAssembly
>
</
assemblyBinding
>
</
runtime
>
<
location
path="Webservice/SomeAPI.asmx"
>
<
system.web
>
<
authorization
>
<
allow
verbs="GET"
users="*"
/>
<
allow
users="*"
/>
</
authorization
>
</
system.web
>
</
location
>
</
configuration
>
Thanks,
Stelios
|
|
|
|
Hi,
Would you know exactly in your code where this exception came from? Also, I noticed that you did not specify the dataConfiguration defaultDatabase value in your config, so I'm assuming your doing the instantiation of the Database object with supplied connection
string name in it right? Please let me know.
Gino Terrado
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com
|
|
Jun 8, 2010 at 12:27 PM
Edited Jun 8, 2010 at 12:40 PM
|
Hello,
It seems that the problem is related with the defaultDatabase. Once I add this property on the web.config the problem is solved.
However, further down the application lifecycle another problem comes up. The web application connection string is pointing on a master database, lets say database MS_DB.
Once the user logs in the website, access is restricted to specific database. Because of this I contruct manually the connection string to map the correct user database:
Database db = DatabaseFactory.CreateDatabase(HttpContext.Current.Session["DatabaseConnString"].ToString());
Once I run the application I then get the following error:
The type Database cannot be constructed. You must configure the container to supply this value.
Description:
An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details:
System.InvalidOperationException: The type Database cannot be constructed. You must configure the container to supply this value.
Source Error:
|
Line 226: {
Line 227: // Database db = DatabaseFactory.CreateDatabase();
Line 228: Database db = DatabaseFactory.CreateDatabase(HttpContext.Current.Session["DatabaseConnString"].ToString());
Line 229: DbCommand dbCommand = db.GetStoredProcCommand("SP_Fetch_DropDownData");
Line 230: db.AddInParameter(dbCommand, "@tablename", System.Data.DbType.String, tablename);
|
How can I fix that?
I know that this is possible:
<connectionStrings>
<clear/>
<add name="MyConnection1" providerName="Oracle.DataAccess.Client" connectionString="Your Connection String Here" />
<add name="MyConnection2" providerName="MSSQL" connectionString="Your Connection String Here" />
</connectionStrings>
But I would prefer doing this programmatically. How can I accomplish this?
Thanks in advance,
Stelios
|
|
|
|
Explicitly supply your connection string name in the instantiation of your database object.
You can do either of the two approach;
Database db = DatabaseFactory.CreateDatabase("MyConnection1"); Or
Database db = EnterpriseLibraryContainer.Current.GetInstance<Database>("MyConnection1"); ~(EntLib 5 recommended)
Gino Terrado
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com
|
|
Jun 8, 2010 at 2:29 PM
Edited Jun 8, 2010 at 2:32 PM
|
Hello and thanks for the reply.
Your examples get the connection string from the config file by name.
In our case the connection strings are not contained in the config files. The database server is the same as the one intially contained in the defualt connection string but we need to change to another database programatically. How is this possible?
Thanks,
Stelios.
|
|
|
|
Sorry I missed that part of the question earlier.
If you need to create a database where the connection string are not coming from the config file you can achieve this by utilizing the constructor of a specific database type you need to create.
The following are as follows:
Let say string myConnectionString= @"Data Source=(local);Initial Catalog=Products;Integrated Security=true";
For SqlDatabase: SqlDatabase sqldb =
new SqlDatabase(myConnectionString);
For Oracle: OracleDatabase oracledb = new OracleDatabase(myConectionString);
For other provider you can user: GenericDatabase generic =
new GenericDatabase(myConnectionstring, OdbcFactory.Instance);
For more details check the documentation
http://msdn.microsoft.com/en-us/library/ff664719(v=PandP.50).aspx.
HTH,
Gino Terrado
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com
|
|
|
|
Thank you very much.
It worked:
SqlDatabase sqldb = new SqlDatabase(myConnectionString);
Regards,
Stelios
|
|
|
|
I have a question regarding this post.
From a design perspective, reading the connection string and using it in Data Access Layer would require a config file in the Data Access Layer project of the solution.
What is the best practice? To have the connection stored either with the web application project or a Data access layer project?
Thanks!
|
|
Editor
Nov 30, 2011 at 2:37 AM
|
A typical approach is to store configuration information in the app.config or web.config. I.e. not in a DLL specific configuration file.
From a design perspective, reading the connection string and using it in Data Access Layer would require a config file in the Data Access Layer project of the solution.
The Data Access Layer will still be able to read configuration stored in the app/web config without requiring a Data Access Layer configuration file.
If you have requirements where you don't want to modify the app/web config then you could look into managing DLL configuration files or some other configuration approach
but that will be extra development work.
Also, since this applies to the original question, I will link to an article on How to change Database in Enterprise
Library 5.0
--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com
|
|
|
|
The Data Access Layer will still be able to read configuration stored in the app/web config without requiring a Data Access Layer configuration file.
Randy - Your afore-mentioned statement answers my question. I wanted to find out if I could access the configuration information that exists in a web.config file part of the Web application project from Data Access Layer DLL.
Thanks for such a prompt response!
Regards,
--raringsunny
|
|
|
|
I have the same error.
Microsoft.Practices.ServiceLocation.ActivationException: Activation error occured while trying to get instance of type Database, key "ConnectionStrings.Oracle.xxx" ---> Microsoft.Practices.Unity.ResolutionFailedException: Resolution of the dependency
failed, type = "Microsoft.Practices.EnterpriseLibrary.Data.Database", name = "ConnectionStrings.Oracle.xxx".
Exception occurred while: while resolving.
Exception is: InvalidOperationException - The type Database cannot be constructed. You must configure the container to supply this value.
My config:
<configSections>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.414.0, Culture=neutral, PublicKeyToken=709072f976b4c05b" requirePermission="true"/>
</configSections>
<dataConfiguration defaultDatabase="ConnectionStrings.Oracle.xxx"/>
<connectionStrings>
<add name="ConnectionStrings.Oracle.xxx" connectionString="DATA SOURCE=des;PASSWORD=zzz;PERSIST SECURITY INFO=True;USER ID=aaa;"
providerName="Oracle.DataAccess.Client" />
My code: I test 3 options
1. Database db = DatabaseFactory.CreateDatabase("ConnectionStrings.Oracle.xxx");
2.
Database db = Microsoft.Practices.EnterpriseLibrary.Common.Configuration.EnterpriseLibraryContainer.Current.GetInstance<Database>("ConnectionStrings.Oracle.xxx");
//~(EntLib 5 recommended)
3.
var
cs = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionStrings.Oracle.xxx"
].ConnectionString;
Database
db = DatabaseFactory
.CreateDatabase(cs);
any good solution ?
|
|
Editor
Jan 13, 2012 at 1:45 AM
Edited Jan 13, 2012 at 2:40 AM
|
The PublicKeyToken in the configuration you posted is incorrect (unless you are building and signing Enterprise Library yourself). It should be:
<configSections>
<section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
</configSections>
It also looks like you are using ODP.NET because the provider is set to Oracle.DataAccess.Client. Or did you want to use System.Data.OracleClient which works out of the box?
If you are using ODP.NET then you should look at the EntLibContrib Oracle ODP.NET Data Provider.
If not, then change the provider to System.Data.OracleClient and it should work.
--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com
|
|
Jan 13, 2012 at 6:27 AM
Edited Jan 13, 2012 at 7:20 AM
|
Thanks.
Using EntLib 4.1 before, all is OK, now using EntLib 5.0 fails for me. I dont understand.
I use ODP.NET and I sign Enterprise Library myself.
I would look your link, but using EntLib 4.1 and ODP.net we not use EntLibContrig, ..
Thanks again.
|
|
|
|
I add more info, for me this code is OK
var key = "ConnectionStrings.Oracle.xxx";
string connectionString = ConfigurationManager.ConnectionStrings[key].ConnectionString;
string providerName = ConfigurationManager.ConnectionStrings[key].ProviderName;
//Database db = Microsoft.Practices.EnterpriseLibrary.Common.Configuration.EnterpriseLibraryContainer.Current.GetInstance<Database>(key);
TestContext.WriteLine("connectionString: " + connectionString);
TestContext.WriteLine("providerName: " + providerName);
DbProviderFactory factory = DbProviderFactories.GetFactory(providerName);
using (DbConnection connection = factory.CreateConnection())
{
connection.ConnectionString = connectionString;
connection.Open();
TestContext.WriteLine("Estado Conexión: " + connection.State);
connection.Close();
}
|
|
Editor
Jan 14, 2012 at 7:58 AM
|
You can't use the Enterprise Library OracleDatabase with the Oracle.DataAccess.Client provider. The built in OracleDatabase is hardcoded to
use the OracleClientFactory DbProviderFactory whereas you want to use the ODP.NET provider (Oracle.DataAccess.Client).
The best way is to get the
EntLibContrib Oracle ODP.NET Data Provider working since it should support everything that you need including configuration files.
Since it looks like you can create the DbProviderFactory you could try to use a GenericDatabase with the ODP.NET OracleClientFactory but I would guess that
you would run into issues for specific Oracle functionality (e.g. refcursor).
You could use it directly:
string connectionString = ConfigurationManager.ConnectionStrings["Connection String"].ConnectionString;
string providerName = ConfigurationManager.ConnectionStrings["Connection String"].ProviderName;
DbProviderFactory factory = DbProviderFactories.GetFactory(providerName);
var db = new GenericDatabase(connectionString, factory);
--
Randy Levy
Enterprise Library support engineer
entlib.support@live.com
|
|
|
|
Thanks a lot. It's great. Now, is all working using right configuration, like in Data.OdpNet.QuickStarts.sln (EntLibContrib)
Now, I have any unit test that using DbProviderFactories.GetFactory(providerName);
providerName: EntLibContrib.Data.OdpNet
and I get this error: System.InvalidOperationException: The requested .Net Framework Data Provider's implementation does not have an Instance field of a System.Data.Common.DbProviderFactory
derived type.
what about DbProviderFactories.GetFactory and EntLibContrib ?
The discussion is here:
http://entlibcontrib.codeplex.com/discussions/286640
Thanks in advanced.
My
code:
[TestMethod]
public void Conectar_con_EntLib_Contrib_y_OdpNet_Test()
{
var key = "ConnectionStrings.Oracle.EntLibContrib";
var cs = System.Configuration.ConfigurationManager.ConnectionStrings[key].ConnectionString;
string connectionString = ConfigurationManager.ConnectionStrings[key].ConnectionString;
string providerName = ConfigurationManager.ConnectionStrings[key].ProviderName;
//Database db = DatabaseFactory.CreateDatabase(key);
Database db = EnterpriseLibraryContainer.Current.GetInstance<Database>(key);
TestContext.WriteLine("connectionString: " + connectionString);
TestContext.WriteLine("providerName: " + providerName);
DbProviderFactory factory = DbProviderFactories.GetFactory(providerName);
using (DbConnection connection = factory.CreateConnection())
{
connection.ConnectionString = connectionString;
connection.Open();
TestContext.WriteLine("Estado Conexión: " + connection.State);
connection.Close();
}
}
|
|
|
|
Hi kiquenet,
Indeed, using DbProviderFactories.GetFactorywith the EntLibContrib OPD.NET provider throw the mentionned exception. Expect a code fix to be released soon in the EntLibContrib source section.
Cheers,
Jeremi
|
|
|
|
Now, it's ok,thanks
[TestMethod]
//[ExpectedException(typeof(System.InvalidOperationException), "The requested .Net Framework Data Provider's implementation does not have an Instance field of a System.Data.Common.DbProviderFactory derived type")]
public void GetFactory_con_EntLib_Contrib_y_OdpNet_genera_InvalidOperationException_fixed()
{
var key = "ConnectionStrings.Oracle.EntLibContrib";
var cs = System.Configuration.ConfigurationManager.ConnectionStrings[key].ConnectionString;
string connectionString =
ConfigurationManager.ConnectionStrings[key].ConnectionString;
string providerName =
ConfigurationManager.ConnectionStrings[key].ProviderName;
//Database db = DatabaseFactory.CreateDatabase(key);
Database db = EnterpriseLibraryContainer.Current.GetInstance<Database>(key);
TestContext.WriteLine("connectionString: " + connectionString);
TestContext.WriteLine("providerName: " + providerName);
DbProviderFactory factory =
DbProviderFactories.GetFactory(providerName);
using (DbConnection connection = factory.CreateConnection())
{
connection.ConnectionString = connectionString;
connection.Open();
TestContext.WriteLine("Estado Conexión: " + connection.State);
connection.Close();
}
}
|
|
|
|
It was damn $%@#$#^% frustrating to get this resolved. Took couple of days to fix this, guys. Urrggghhhh.
Error: Activation error occured while trying to get instance of type Database, key ""
Inner Exception: Resolution of the dependency failed, type = Microsoft.Practices.EnterpriseLibrary.Data.Database
Specifics: I was running VS 2010 on Windows 7, Enlib 5.0.
The following worked for me. Wanted to spread the word around. It may work for you guys.
-
Make sure you have proper reference to Microsoft.Practices.Unity.dll
-
Get the latest service pack for VS 2010
|
|