DAAB & Unity

Nov 9, 2009 at 8:40 PM

Hi,

I followed through the great tutorial from David Hayden on the Unity & DAAB from http://www.davidhayden.com/blog/dave/archive/2008/05/19/EnterpriseLibrary4DataAccessApplicationBlockDAABUnityIoCTutorial.aspx . I'm using DAAB4.1 and Unity1.2 from Enterprise Application Block 4.1 version. It doesn't allow me to specify the 2nd connection, and it always uses the default connetion.<font size="2">

 

</font>

IUnityContainer container = new UnityContainer();

container.AddNewExtension<EnterpriseLibraryCoreExtension>();

container.AddNewExtension<DataAccessBlockExtension>();

<font size="2" color="#000080"><font size="2" color="#000080">

var

</font></font><font size="2" color="#000080">

 

</font>

database = container.Resolve<Database>("connection2");

This never use connetion2 and always use the default connetion.

Is this because of version 4.1 changed something? At lease it is not consistent w/ version 4.0 for this funtionality.

Thanks

Nov 10, 2009 at 1:42 AM

I can't repro this case, I'm getting the correct Database instance both for the default and non-default connection string.  Are you sure connection2 is not the same with your default connection string?

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Nov 10, 2009 at 12:26 PM
AvanadeSupport wrote:

I can't repro this case, I'm getting the correct Database instance both for the default and non-default connection string.  Are you sure connection2 is not the same with your default connection string?

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Sarah,

Thanks for the response. Below are my code and app.config. I never see the test2, and no matter what string you put there it always goes to test connection.

namespace DBAccessBlock {

    using Microsoft.Practices.Unity;
    using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Unity;
    using Microsoft.Practices.EnterpriseLibrary.Data.Configuration.Unity;
    using Microsoft.Practices.EnterpriseLibrary.Data;

    class Program {

        static void Main(string[] args) {

            IUnityContainer container = new UnityContainer();
            container.AddNewExtension<EnterpriseLibraryCoreExtension>();
            container.AddNewExtension<DataAccessBlockExtension>();

            CustomerDAO dao = container.Resolve<CustomerDAO>("test2");
        }
    }

    class CustomerDAO {

        private readonly Database database;

        public CustomerDAO(Database database) {
            this.database = database;
        }

    }
}

App.config

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data" />
  </configSections>
  <dataConfiguration defaultDatabase="test" />
  <connectionStrings>
    <clear/>
    <add name="test" connectionString="Database=mydb;Data Source=localhost;Port=3306;User Id=name;Password=password"
        providerName="MySql.Data.MySqlClient" />
    <add name="test2" connectionString="Database=mydb;Data Source=localhost;Port=3305;User Id=name2;Password=password2"
        providerName="MySql.Data.MySqlClient" />
  </connectionStrings>
</configuration>

Nov 12, 2009 at 2:55 AM
Edited Nov 12, 2009 at 2:58 AM

The string parameter in the Resolve method does not correspond to the name of the connection string, it corresponds to the name of the type mapping you used for the CustomerDAO type.  What you could do here is to register a type mapping for the CustomerDAO and specify the Database dependency you want.

 

You can also chose not to use a named registration:

 

 

container.RegisterType<CustomerDAO>(new InjectionMember[] { new InjectionConstructor(new ResolvedParameter(typeof(Database), "test2")) });
CustomerDAO dao = container.Resolve<CustomerDAO>();


Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

 

  

container.RegisterType<CustomerDAO>("myDb", new InjectionMember[] { new InjectionConstructor(new ResolvedParameter(typeof(Database), "test2")) });
CustomerDAO dao = container.Resolve<CustomerDAO>("myDb");

Dec 1, 2009 at 7:59 AM
Edited Dec 1, 2009 at 2:47 PM

I followed through the knowledge tutorial from David Hayden on the Unity & DAAB............
I created a 3-tier layer application.
named DAL for one of them to access database using the DATAACCESSBLOCK..
This contained 2 class files.

1. DStoredProcedureReader with following code...........
2. DStoredProcedure with the following code...........

3. APP.CONFIG is well constructed.

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>
  <dataConfiguration defaultDatabase="Northwind" />
  <connectionStrings>
    <add name="Northwind" connectionString="Data Source=.;Initial Catalog=Northwind;Integrated Security=True"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

but when i execute the application i am stoping at
var databasegateway = container.Resolve<DStoredProcedure>();

and the error is ............
Resolution of the dependency failed, type = "DAL.DStoredProcedure", name = "".
Exception message is: The current build operation (build key Build Key[DAL.DStoredProcedure, null]) failed:
The parameter db could not be resolved when attempting to
call constructor DAL.DStoredProcedure(Microsoft.Practices.EnterpriseLibrary.Data.Database db).
(Strategy type BuildPlanStrategy, index 3)
Please anyone help me in this regards,
Thanks in advance.
agurukumar@gmail.com
Dec 1, 2009 at 8:34 AM

Could you try opening your app.config in xml editor?  Check if there is a value for the defaultDatabase property of your dataConfiguration section.

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

 

Dec 1, 2009 at 9:13 AM

<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <configSections>
    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
  </configSections>
  <dataConfiguration defaultDatabase="Northwind" />
  <connectionStrings>
    <add name="Northwind" connectionString="Data Source=.;Initial Catalog=Northwind;Integrated Security=True"
      providerName="System.Data.SqlClient" />
  </connectionStrings>
</configuration>

Dec 1, 2009 at 9:32 AM

i am unable track the issue,

when i worked exactly according to  Haydens tutorial like creating

and using in the same console application its working fine.

But in n-tier arch. its not working.

is there any restriction of location of the app.config?

where to create?

 

Dec 1, 2009 at 9:39 AM

Where is your app.config? Is it in the host project? I tried out the files you sent me and I can resolve the DStoredProcedure class successfully.  BTW, the code you posted above is mixed up, both are DStoredProcedureReader classes

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Dec 1, 2009 at 9:41 AM

Yes, the configuration file should be in the host project, not in class libraries.  (Although you can make use of FileConfigurationSource)

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Dec 1, 2009 at 10:01 AM

Found it, your web.config did not have a value for the DefaultDatabase property

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Dec 1, 2009 at 10:17 AM

Please check the prior posting done by me please everything is corrected.

 

Dec 1, 2009 at 10:22 AM

I've already seen your code.  Does editing your config and setting the DefaultDatabase property still doesn't solve your problem?

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Dec 1, 2009 at 10:28 AM

no............ :(

 

Dec 1, 2009 at 10:30 AM
Edited Dec 1, 2009 at 10:35 AM

Ok, I'll send you the copy of the working version of the solution you sent me...[DONE]

 

Sarah Urmeneta
Global Technology and Solutions
Avanade, Inc.
entlib.support@avanade.com

Dec 1, 2009 at 11:32 AM
Edited Dec 1, 2009 at 2:55 PM

 

According to David Hayden wonderful  tutorial on the Unity & DAAB............

step 1: Create a 3-tier layer application.

step2:Add the the following references (mostly the path is Program Files\Microsoft Enterprise Library 4.1 - October 2008)

Microsoft.Practices.EnterpriseLibrary.Common.dll
Microsoft.Practices.EnterpriseLibrary.Data.dll
Microsoft.Practices.ObjectBuilder2.dll
System.Configuration.dll
Microsoft.Practices.Unity.dll
Microsoft.Practices.Unity.Configuration.dll

step 3:Create a class file DStoredProcedure.cs with following code...........

using System.Data;
using Microsoft.Practices.EnterpriseLibrary.Common;
using Microsoft.Practices.EnterpriseLibrary.Data;
using Microsoft.Practices.ObjectBuilder2;

    public class DStoredProcedure
    {
        /// <summary>
        /// Methods in this class excutes your stored procedure and returns the result.
        /// Obbserve the constructor which requires the Database before getting called.
        /// returns the datareader.
        /// </summary>
        private readonly Database _db;
        public DStoredProcedure(Database db)
        {
            _db = db;
        }

        public IDataReader ExecuteReader(string spname, params object[] parameters)
        {
            return _db.ExecuteReader(spname, parameters);
        }    

    }

step 4: Create another Class file DStoredProcedureReader.cs with the following code...........

using Microsoft.Practices.EnterpriseLibrary.Data.Configuration.Unity;
using System.Data;
using System.Configuration;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Unity.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Unity;
using Microsoft.Practices.EnterpriseLibrary.Data.Configuration;
using Microsoft.Practices.EnterpriseLibrary.Common.Configuration;

    public class DStoredProcedureReader
    {
        /// <summary>
        /// Actual implementation of the Enterprise data access block
        /// This is where the container must be added with  
        /// DataAccessBlockExtension, EnterpriseLibraryCoreExtension
        /// for implementing the dataaccess block features
        /// where it retrives the connection string and the defaultdatabase
        /// from the web.config file.
        /// </summary>
        public DStoredProcedureReader()
        {
                       
        }
        public IDataReader SPReturns(string spname, params object[] parameters)
        {
            IUnityContainer container = new UnityContainer();
            container.AddNewExtension<EnterpriseLibraryCoreExtension>();
            container.AddNewExtension<DataAccessBlockExtension>();

            // This is the place where database is retrieved from the web.config file using the enterprise blocks
            var databasegateway = container.Resolve<DStoredProcedure>();
            var reader = databasegateway.ExecuteReader(spname, parameters);

            return reader;
        }

    }

step 5:Most important part....

Add the following in the web.config file…..

<dataConfiguration defaultDatabase="Northwind" />

     <connectionStrings>

          <add name="Northwind" connectionString="Data Source=.;Initial Catalog=Northwind;Integrated Security=True"

            providerName="System.Data.SqlClient" />

     </connectionStrings> 

==================================================================

The DStoredProcedureReader calls the DStoredProcedure for executing the stored procedure.

After returning to DStoredProcedureReader, this method returns datareader while can he used

for displaying the data.

Execute your appllication....
=======================================================================

Note:

web.config is used with web applications. web.config will by default have several configurations required for

the web application. You can have a web.config for each folder under your web application.

app.config is used for windows applications. When you build the application in vs.net, it will be automatically

renamed to <appname>.exe.config and this file has to be delivered along with your application.

=======================================================================

I'm very much thankful to genius David Hayden for such a wonderful video tutorial on

on the Unity & DAAB (viz., http://www.davidhayden.com/blog/dave/archive/2008/05/19/EnterpriseLibrary4DataAccessApplicationBlockDAABUnityIoCTutorial.aspx )

I also thank Sarah for the wonderful technical support in accomplishment of this task.

Thanks to everyone and I hope this post is helpful

A.R.R.Guru Kumar (agurukumar@yahoo.co.in)