简体   繁体   English

数据库工厂设计

[英]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. 我将providertype存储在我的web.config的自定义部分中,并试图创建一个工厂,该工厂根据设置的提供程序实例化正确的DAL类。

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 . 上面的代码目前将存储在web.config的整个命名空间带到相关的DAL类,并且由于它仅创建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? 我怎样才能建立一个通用工厂,这样我就可以传入要实例化的提供程序类型( 例如SqlServer)和任何类( 例如ArticleDAL)

Thank you in advance. 先感谢您。

I would look into using a proper dependency injection framework, personally I like NInject . 我个人会喜欢使用一个合适的依赖注入框架,我喜欢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. 这些映射可以在web.config中,也可以在应用程序启动时的某些配置代码中。 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. 因此,您可以要求一个IArticleDAL实例,如果IArticleDAL需要一个IDbConnection实例来访问数据库,则NInject将自动创建一个实例并将其传递给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? ...我如何建立一个通用工厂,这样我就可以传入我想实例化的提供程序类型(例如SqlServer)和任何类(例如ArticleDAL)?

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. 我认为您已经在这里了-目前您正在传递一个最终在web.config中设置的值-因此不是特别动态。

Rather than passing in the whole value from web.config you could pass in just the class identifier. 您可以只传递类标识符,而不是从web.config传递整个值。

...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. 我以前没有做过,就像您一样,我总是从web.config中传递一个值。 The trick is deciding: where the responsibility of deciding which DAL class gets loaded sits. 诀窍在于决定:决定加载哪个DAL类的责任在哪里。

It can't be in the Business Layer (BL) - because the BL shouldn't know anything about the Data Access Layer (DAL). 它不能在业务层(BL)中-因为BL不应对数据访问层(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? 我可以尝试进一步回答,但有了更多信息,尤其是可以阐明问题的信息,它将变得更加容易:决定加载哪个DAL类的责任在哪里?

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. 只需消除所有这些添加了慢速和错误代码的第三方层,并通过实现ProviderBase即可使用Provider模式中内置的.net框架,即由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. 我们必须为几个不同的数据库编写存储过程,而必须为每个数据库编写特定的DAL却是一个很大的麻烦,但它确实工作得很好。

I'm wondering why not use Microsoft's own solution for this kind of work? 我想知道为什么不使用Microsoft自己的解决方案来进行此类工作? DbProviderFactories class provides GetFactory method which takes the provider name as input. DbProviderFactories类提供了GetFactory方法,该方法将提供程序名称作为输入。

If you have provider in your web.config , then, 如果您在web.config有提供者,那么,

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. 一旦获得连接对象,您就可以从其中获得几乎所有其他内容,例如DbCommand,DbDataReader等。

您需要使用AbstractFactory模式。

The Data Access Object may help? 数据访问对象可能有帮助吗? (the link is in java but the concept is still the same) (链接在java中,但是概念仍然相同)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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