简体   繁体   中英

Database Factory Design

I am making an app which supports multiple databases. The beerhouse architecture instantiates the correct class from the correct provider using the singleton below.

  static private ArticlesProvider _instance = null;
  static public ArticlesProvider Instance
  {
     get
     {
        if (_instance == null)
           _instance = (ArticlesProvider)Activator.CreateInstance(
              Type.GetType(Globals.Settings.Articles.ProviderType));
        return _instance;
     }
  }

I have the providertype stored into a custom section in my web.config and am trying to create a factory which instantiates the correct DAL class based on the set provider.

The above currently takes the whole namespace stored in the web.config , to the relevant DAL class and is a bit limited as it only creates instances of the ArticlesProvider . How can I make a generic factory, so I can pass in the providertype eg SqlServer and any class eg ArticleDAL , which I wish to instantiate?

Thank you in advance.

I would look into using a proper dependency injection framework, personally I like NInject . This will give you all the tools you need to break the dependency between your application and the underlying database.

You register mappings with the framework, from interfaces to concrete types. These mappings could be in web.config, or in some configuration code in your application startup. The framework will instantiate the classes for you - injecting further dependencies if required.

So you can ask for an instance of IArticleDAL, and if IArticleDAL requires an instance of IDbConnection to access a DB then NInject will automatically create one and pass it to the constructor of the implementation of IArticleDAL.

Anyway - the documentation explains it much better... but in summary the code you've extracted above is just a primitive starting point for proper dependency injection.

...how can i make a generic factory, so I can pass in the providertype eg SqlServer and any class eg ArticleDAL which i wish to instantiate?

I think you're pretty much there - at the moment you're passing in a value which ultimately is set in web.config - and so isn't particularly dynamic.

Rather than passing in the whole value from web.config you could pass in just the class identifier.

...how can i make a generic factory...

I haven't done this before, like you I've always passed in a value from web.config. The trick is deciding: where the responsibility of deciding which DAL class gets loaded sits.

It can't be in the Business Layer (BL) - because the BL shouldn't know anything about the Data Access Layer (DAL).

I can try answering further but it'd be easier with more information, specifically information that sheds light on the question: where does the responsibility of deciding which DAL class gets loaded sit?

Just do away with all these 3rd party layers that add slow and buggy code and just use the .net framework built in Provider pattern by implementing ProviderBase , ie as used by the MembershipProvider. The framework will take care of the rest.

We have to write stored procedures for a few different databases and while it is a major pain to have to write specific DALs per database it does work great.

I'm wondering why not use Microsoft's own solution for this kind of work? DbProviderFactories class provides GetFactory method which takes the provider name as input.

If you have provider in your web.config , then,

var conn = DbProviderFactories.GetFactory("providerName").CreateConnection();

Once you get the connection object, you can get pretty much everything else from it like the DbCommand, DbDataReader etc.

您需要使用AbstractFactory模式。

The Data Access Object may help? (the link is in java but the concept is still the same)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM