Unity and Data Access, using configuration

Jun 5, 2009 at 4:37 PM
Edited Jun 5, 2009 at 4:44 PM

I'm new to Unity, and have had success with my initial simple IOC activites.  Now I'm trying to wire up a Database object from the Data Access Application Block into a DAO implementation I have, using XML config.  This is with Unity 1.2 and MEL 4.1.  I found a blog and an MSDN link on how to wire this up with code, but can't find a good example of what to do in XML.  I've added the requisite  extension tags, which seem to be fine:

 <extensions> <add type="Microsoft.Practices.EnterpriseLibrary.Common.Configuration.Unity.EnterpriseLibraryCoreExtension, Microsoft.Practices.EnterpriseLibrary.Common" /><add type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.Unity.DataAccessBlockExtension, Microsoft.Practices.EnterpriseLibrary.Data" /></extensions>

A database named "SomeDB" has been defined using the MEL GUI in web.config (valid connect string, Oracle ODP.Net provider).  So now I want a Database object injected into my DAO that uses this "SomeDB" connection string and provider configuration from DAB.  The DAO class takes a Database object as a constructor arg, so constructor injection was used.  I tried this type def:

<type type="ISomeDAO" mapTo="SomeDaoImpl" name="DabDaoImpl"> <lifetime type="singleton" /><typeConfig><constructor><param name="database" parameterType="Database"><dependency name="appDb" /></param></constructor></typeConfig></type>

The idea was that I'd configure the appDb mapping next for the Microsoft.Practices.EnterpriseLibrary.Data.Database type, which is where I get confused.  In DAB there is a static DatabaseFactory class that offers a CreateDatabase() method which would be fine in code, but  I can't use from Unity config as far as I can tell. So am I stuck with code to do this?  I looked at the Database class constructors, but only saw a method signature that takes a string and a provider factory object.  I was hoping the DataAccessBlockExtension support would handle this sort of thing, and so concluded I'm probably doing something wrong. 

So, is the above approach right to start with?  Should I be wiring in a Database object?  If so, how can I define one in XML to be injected, using the named configuration in the DAB config?

Searching on this topic has come up empty, and I'd like to know if I'm stuck with code in this case, or if there's a way to do this wiring in configuration.  This MSDN link makes it sound like I should be able to do what I'm after, after it shows how dto do the code-based approach, but doesn't say how to do it from config. http://msdn.microsoft.com/en-us/library/cc511706.aspx

Thanks in advance for any tips. 

Jun 5, 2009 at 6:12 PM

For now I've bailed on the idea of injecting a Database or a Database Factory.  Instead I'm injecting the DAB configuration name in a string, and doing the DatabaseFactory.Create(xxx) method to get my database object, which works fine.  But if anyone knows of a better way, I'd like to hear :-)

Jun 9, 2009 at 3:40 AM

Well, you said the connection string was named "SomeDB", but in the <dependency> tag you gave the name "appDb". If this is indeed the config you were using, this is the problem - they need to line up. The name you give in the <dependency> tag is the one that's used to resolve from the container.

If you resolve the database directly from the container, do you get one? That would be my first question. Can you do:

    container.Resolve<Database>("SomeDB");

and get back the correct value?

If that's not it, could you please post a small, complete example, including complete config file and the code used to set up the container and resolve values? It should just work.

 

 

 

Jun 9, 2009 at 12:40 PM

Sorry, when I posted, I changed the names in the config to remove our real names, and missed one.  Unfortunately, referencing a Database object correctly is not the issue I'm after.  I can't figure out how to model a DAB Database object in the first place, without using code.  The DAB requires a call to a static create method on the DatabaseFactory class to create a Database object.  That's what I couldn't figure out how to define in XML.  If I had a def for that, I could point a Resolve or a dependency tag to it to get the mapping.

Since the static method is involved, and i couldn't determine an alternative, I made a constructor like this in the DAO implementation:

        private Database db;

        public SomeDaoImpl(string dbConfigName)
        {
            db = DatabaseFactory.CreateDatabase(dbConfigName);
        }
 

The constructor injection looks like this, where the string value "SomeDB" matches a DAB configuration (connect string and provider) in web.config:

          <type type="ISomeDAO" mapTo="SomeDaoImpl" name="daoImpl">
            <lifetime type="singleton" />
            <typeConfig>
              <constructor>
                <param name="database" parameterType="System.String">
                  <value value="SomeDB" />
                </param>
              </constructor>
            </typeConfig>
          </type>
 

This wires into my stuff just fine, and works fine. So the original question was after this issue: is there a way to configure the Database instance directly in XML, since the creation of one requires a static method call on the DatabaseFactory class? 

Since the workaround only requires one small constructor in each DAO implementation, this original question is just about moot.  When I did the first post, I hadn't figured out the simple work-around (too dumb :-)), and thought I was stuck.  So no biggie if it stays the way it is.

Thanks for the response!  Lemme know if you think there was a better way to handle the DatabaseFactory static method issue than what I did above. 

Jun 10, 2009 at 4:11 AM

Well, the way it SHOULD work is that you add the core extension, you add the Data block extension, you configure your connection strings, and that's it. You shouldn't need to configure anything else, it should just work. You shouldn't need your DAO Impl with the constructor. You should be able to inject a database directly.

 

-Chris