How To Create Custom Database With Enterprise Library 2.0 Data Access Block

Posted by Hugh Ang at 1/21/2007 08:54:00 PM

There seems to be little documentation on how to create custom database object to be used for Enterprise Library 2.0 Data Access block. Tom Hollander in this blog confirms that this is definitely a possibility:


In the new version, we still have the SqlDatabase and OracleDatabase class – but we also have a new GenericDatabase class. The GenericDatabase can be used with any .NET managed provider (including the ODBC and OLE-DB providers that ship with .NET) – but the catch is that it doesn’t support all of the DAAB functionality. Most significantly, the overloads that use parameter discovery do not work (since these methods aren’t supported on .NET’s DbConnection or DbCommand classes). There’s still the option to build your own Database-derived classes to support this advanced functionality and provide improved database transparency – this is why we built SqlDatabase and OracleDatabase – but at least you’ll be able to use most of the block against any type of database.


Since I installed Firebird, I have been itching to write a custom Database for Firebird in the EntLib 2.0 framework. I know there are customers who want to do this as well because they have Sybase, DB2 in their environment. The GenericDatanase would be an option with ODBC and OLEDB. But for the long term, it makes sense to leverage the native ADO.NET providers if they do exist.

So I started digging into the source code and trying to figure out how a custom Database object would be created by EntLib besides the three ones provided out of the box. Finally I came upon the GetProviderMapping() function of DatabaseConfigurationView class:


 

        public DbProviderMapping GetProviderMapping(string name, string dbProviderName)

        {

            DatabaseSettings settings = this.DatabaseSettings;

            if (settings != null)

            {

                DbProviderMapping existingMapping = settings.ProviderMappings.Get(dbProviderName);

                if (existingMapping != null)

                {

                    return existingMapping;

                }

            }

 

            DbProviderMapping defaultMapping = this.GetDefaultMapping(name, dbProviderName);

            if (defaultMapping != null)

            {

                return defaultMapping;

            }

 

            return this.GetGenericMapping();

        }





This function calls the ProviderMappings property of the DatabaseSettings class:


 

    public class DatabaseSettings : SerializableConfigurationSection

    {




 



        // code ommited for brevity




         

        /// <summary>

        /// Holds the optional mappings from ADO.NET's database providers to Enterprise Library's database types.

        /// </summary>

        /// <seealso cref="DbProviderMapping"/>

        [ConfigurationProperty(dbProviderMappingsProperty, IsRequired = false)]

        public NamedElementCollection<DbProviderMapping> ProviderMappings

        {

            get

            {

                return (NamedElementCollection<DbProviderMapping>)base[dbProviderMappingsProperty];

            }

        }

    }



This shows that the configuration drives the creation of the custom Database, if any. So I openned up the EntLib configuration console and now the "Custom Mapping Providers" made sense - all we have to do is to provide a mapping between a name and a custom Database type.



I will detail creating the assembler class along with the custom Database object in a future blog. To see how these all work together, Here is the CreateObject() function of the DatabaseCustomFactory class that provides a clear view how the mapping is queried, then assembler is created from the mapping before the Database gets created. :


 

        public object CreateObject(IBuilderContext context, string name, IConfigurationSource configurationSource, ConfigurationReflectionCache reflectionCache)

        {

            DatabaseConfigurationView configurationView = new DatabaseConfigurationView(configurationSource);

            ConnectionStringSettings connectionStringSettings = configurationView.GetConnectionStringSettings(name);

            DbProviderMapping mapping = configurationView.GetProviderMapping(name, connectionStringSettings.ProviderName);

 

            IDatabaseAssembler assembler = GetAssembler(mapping.DatabaseType, name, reflectionCache);

            Database database = assembler.Assemble(name, connectionStringSettings, configurationSource);

 

            return database;

        }

1 comments:

njbaige said...

Hello sir,

It is first time to read your blog,and feel it's so helpful to us, thanks.
Hope more articles can be shared.