Upgrading from v0.8 to v0.9

When development began on Database Abstraction, the goal was to use as many interfaces as possible. We had also seen type parameters passed, but were not aware of how to actually use them. In the intervening months since v0.8 was release, we learned that we were using some concrete classes where interfaces would be more appropriate; we also learned the quite-simple task of accepting type parameters, inspecting them, and utilizing them.

The goal was to mark the concrete classes as obsolete, with preference for the new classes; however, there were some issues with subclassing, mostly related to the fact that the constructors were considered ambiguous (evidently params IQueryLibrary[] classes and params Type[] providers are indistinguishable from each other in certain cases). With the project still being not-yet-1.0, we decided to simply remove these methods, and use interfaces and types instead.

The table below shows the old and new interfaces and methods. The concepts are the same; only the names and types have changed.

Old New
IQueryLibrary IDatabaseQueryProvider *
- GetQueries(Dictionary<string, DatabaseQuery> - Queries(IDictionary<string, DatabaseQuery>
IQueryFragmentProvider (same)
- Fragments(Dictionary<string, QueryFragment>) - Fragments(IDictionary<string, QueryFragment>)
IDatabaseModel IParameterProvider
- Dictionary<string, object> DataParameters() - IDictionary<string, object> Parameters
IDatabaseService ** (same)
- SQL(string, Dictionary<string, object>) - SQL(string, IDictionary<string, object>
- SQL(string, IDatabaseModel) - SQL(string, IParameterProvider)
DbUtils (same)
- Dictionary<string, object> SingleParameter(string, object) - IDictionary<string, object> SingleParameter(string, object)
- ... QueryFragmentProviderList(...) - deleted

* IQueryProvider exists in System.Linq, so we considered that name to be taken.
** "SQL" could be replaced with Select, SelectOne, Insert, Update, or Delete.

Additionally, the constructors and utility methods now take types and interfaces instead of concrete class instances. For example, both DatabaseService(params IQueryLibrary[] classes) and DatabaseService(List<IQueryFragmentProvider> fragments, params IQueryLibrary[] classes) are both now covered by the new constructor DatabaseService(params Type[] providers) .

IDatabaseService service = new PostgresDatabaseService(
    DbUtils.QueryFragmentProviderList(new FragmentProvider1(), new FragmentProvider2()),
    new FirstQueryLibrary(), new SecondQueryLibrary(), new ThirdQueryLibrary());

IDatabaseService service = new PostgresDatabaseService(typeof(FragmentProvider1),
    typeof(FragmentProvider2), typeof(FirstQueryLibrary), typeof(SecondQueryLibrary),

DbUtils.CreateDatabaseService has also been updated with this signature, and its return type is IDatabaseService . So, a better way to do the above would be

var service = DbUtils.CreateDatabaseService(connectionString, providerName,
    typeof(FragmentProvider1), typeof(FragmentProvider2), typeof(FirstQueryLibrary),
    typeof(SecondQueryLibrary), typeof(ThirdQueryLibrary));

This is actually the preferred way of creating connections, as swapping the concrete provider could be as easy as a Web.config file change. A few notes on this:
  • The order of types is irrelevant; the code will assemble all fragments and queries before trying to put them all together.
  • Types should be classes that implement at least one of either the IDatabaseQueryProvider or IQueryFragmentProvider interfaces; they may implement both. You can pass in any type you like, but those are the only two that are utilized.
So, there you have it. v0.9 is not a drop-in replacement for v0.8, but with minimal code changes, it should work exactly the same. This also gives flexibility, particularly with parameters; if you want to implement a SortedDictionary instead of the regular Dictionary , the new signature now supports it.

The examples on the site have been updated; if the changes aren't clear above, reading through the examples may help.

Last edited May 6, 2012 at 5:08 AM by danielsummers, version 4


No comments yet.