C# DAL中使用单例模式的利弊

C# DAL中使用单例模式的利弊,c#,singleton,data-access-layer,C#,Singleton,Data Access Layer,我曾要求使用DAL实现的单例模式,但我认为很难汇集连接、使用事务等等 我想知道的优点和缺点,还想知道最好的方式,以池的连接,因为可以有超过500个并发用户的网站,我正在开发 DB服务器是Oracle 10g DAL使用Enterprise library 3.1我不知道DAL,但单例模式是一种在保持良好封装的同时实现数据全局化的好方法。在DAL中使用单例作为数据库连接工厂是非常常见的。它允许您更轻松地插入工厂的不同实现,而无需更改大量代码。很多人似乎不喜欢singleton模式,但我认为它适合这

我曾要求使用DAL实现的单例模式,但我认为很难汇集连接、使用事务等等

我想知道的优点和缺点,还想知道最好的方式,以池的连接,因为可以有超过500个并发用户的网站,我正在开发

DB服务器是Oracle 10g


DAL使用Enterprise library 3.1

我不知道DAL,但单例模式是一种在保持良好封装的同时实现数据全局化的好方法。

在DAL中使用单例作为数据库连接工厂是非常常见的。它允许您更轻松地插入工厂的不同实现,而无需更改大量代码。很多人似乎不喜欢singleton模式,但我认为它适合这种类型。

连接池的最佳实践是不要自己实现它,而是让ADO.NET框架来处理它

可以将连接池选项设置为连接字符串中的参数。然后,使用该字符串打开的每个连接都将由框架实现和管理的连接池提供。当您关闭或处置OracleConnection时,基础连接不会被破坏,而是会返回到池中

这里描述了这一点:

关于单例的一般用法:我用它们来包装数据访问层,它一直工作得很好


请注意,事务仅适用于特定连接,而不适用于整个数据库。这意味着您可以运行多个线程,每个线程都可以通过独立的事务对数据库进行读写,前提是每个线程使用单独的OracleConnection实例

我认为如果您使用或不使用单例,您不会有性能差异,因为您仍然可以在同一时间在同一方法上运行多个线程。如果您注意到没有将在所有线程中共享的内部字段,那么一切都会正常工作

最后,管理连接池的类需要是线程安全的,并且最终会产生一些可能影响性能的锁,但它们都是必需的。(它是在框架内部生成的,您无论如何都不能更改它的行为)

如果您决定不使用单例,请确保您的DAL实例是lightweight,因为这可能会有所不同,但通常不会

注意:谈到连接池,您必须注意的唯一重要事项是遵循“晚开早关”模式。这意味着,尽可能延迟连接的打开,并在完成所有需要的操作后尽快关闭连接


在使用这个神奇的规则构建所有系统之后,您可以使用连接字符串参数来更改一些池选项(初始大小、最大大小等)

对于在DAL中使用单例,我感到有点不安。如果我想使用多个数据库后端该怎么办。也许我想使用MsSQL进行发票验证,但使用Active Directory进行身份验证。或者我想用MySQL发布论坛帖子,但用PostgreSQL进行地理聚类(对我来说更现实,呵呵)。当我无法通过模拟数据库连接进行测试时,单例接口可能会使测试数据库层变得更具挑战性。

单例模式非常适合DAL——我在自己的企业web应用程序中使用它(在20多个单例类中有数百个用户和2000多个方法)。连接池确实由ado.net和sql server本身处理得最好。如果您想拥有多种类型的后端服务器,这不是问题。即使使用单例模式,您也可能需要一个集中式数据访问类,该类处理实际直接调用数据库的细节(参数、文本/过程名称、凭据/连接字符串都传入)

在我的情况下,单个数据库上的每个方法都与数据库中的存储过程1:1对应。这本质上为每个存储过程创建了一个C#“前端”钩子,因此从语法上讲,它们可以像本机C#代码一样被调用。这使得对DAL的调用非常简单。我有多个单身,因为有大量的SP问题。每个SP都有一个前缀,比如开发、财务、组织等等。然后我有一个对应于每一个的单例类,比如开发、财务或组织。因此,sp Organization_ViewData在C中是名为Organization的单例类上名为ViewData的方法


当然,这只是一种方法,但我发现,在过去的六年中,我可以与多个开发人员和大量代码一起很好地工作。最重要的是,一致性是关键。如果前端程序员正在查看某个单例代理上的方法名称,那么应该告诉他们该方法将进入数据库端的确切位置。这样,如果出现问题,或者如果有人必须搜索代码以试图理解它,那么就不需要进行太多的跟踪。

我添加了另一段来讨论事务。但是如果我们在应用程序之间共享单个DAL对象,我们如何使用ADO.net的连接池,因为单个DAL对象在任何时候都只需要一个连接。很可能,来自不同应用程序的每个调用都将位于不同的线程上。将只有一个DAL对象,但框架将在不同的线程上同时调用方法。每个线程都需要自己的连接。