如何适当地设计数据访问层?
Posted
技术标签:
【中文标题】如何适当地设计数据访问层?【英文标题】:How do I design a Data Access Layer appropriately? 【发布时间】:2011-06-04 19:49:43 【问题描述】:我有以下数据访问层 (DAL)。我想知道它是否设置正确,或者我是否需要改进它?
public class User
//Persistence methods
static class UserDataAccess
UsersDAL udal = // Choose SQL or FileSystem DAL impl.
InsertUser(User u)
// Custom logic , is 'u' valid etc.
udal.Insert(u);
abstract class UsersDAL
GetUserByID();
InsertUser(u);
...
// implementaitons of DAL
static class UsersSQLStore : UsersDAL
static class UsersFileSystemStore : UsersDAL
我将存储层从 User 类中分离出来,以访问进一步调用任何自定义 DAL 的方法集合。
在 DAL 实现中使用 static
是否正确?
请提出更正或改进的方法。我没有很多分层编写代码的经验。
【问题讨论】:
如果您不能花时间完整地说明您的问题(使用 Pl. 而不是 Please),那么您如何期望有人花时间回答您的问题或帮助您? @George,我不知道这是否会伤害到某人,但为了避免人们阅读过多,我经常使用它。相反,我专注于写下我的例子。这并不意味着我不欣赏人们的时间和他们的反应。 为什么要这样做而不是使用像 LLBLGen 或 Dapper 这样的 ORM?无需重新发明***。 【参考方案1】:Davy Brion 有一组关于这个主题的优秀博文:located on GitHub
【讨论】:
您包含的链接现已损坏。请更新它。【参考方案2】:我的拙见
-
如果用户没有任何层次结构,则使用接口而不是抽象类。
编写一个通用 DAL,以便您可以将其重用为 DAL 层的外观。
通过 DI 框架解析具体的 DAL
【讨论】:
【参考方案3】:这些类都不应该是static
。我认为你也不应该将你的类命名为DAL
,因为它是数据访问层的缩写,而一个类本身并不是一个层(至少在我看来)。您可以改用广泛采用的术语repository。我建议您执行以下操作:
public class User
public abstract class UserRepository
public abstract void InsertUser(User user);
public class SqlUserRepository : UserRepository
public override void InsertUser(User user)
//Do it
public class FileSystemUserRepository : UserRepository
public override void InsertUser(User user)
//Do it
public class UserService
private readonly UserRepository userRepository;
public UserService(UserRepository userRepository)
this.userRepository = userRepository;
public void InsertUser(User user)
if(user == null) throw new ArgumentNullException("user");
//other checks
this.userRepository.InsertUser(user);
注意UserService
在其构造函数中注入了抽象类UserRepository
的实例。您可以使用Dependency Injection (DI) 框架自动为您执行此操作,例如来自Castle Project 的Windsor Castle。它将允许您在配置文件或代码中指定从抽象(UserRepository
)到具体实现(例如SqlUserRepository
)的映射。
希望这能为您指明正确的方向,如果您需要更多信息,请询问。
【讨论】:
这就是模板模式。正如 Hoffmann 和 Jani 所建议的那样,您的方向是正确的 很好的解释。为什么我应该使用静态?如果不是存储库,对于 UserService,我猜我可以将其设为静态吗?还有 1 件事(可能与 DAL 无关):如果尝试插入现有用户,那么谁应该通过构造函数进行检查、UserService 或 User 类本身(因为它在新的时候不知道存在性) @Munish Goyal,你不应该使用static
,因为没有必要。如果使用不当,static
会在您的应用程序中引入不必要的状态,这使得调试变得更加困难,最重要的是,它非常难以自动测试。您可能想在这里阅读static
的确切含义:msdn.microsoft.com/en-us/library/98f28cdx%28vs.71%29.aspx
@Munish Goyal,我认为UserService
应该通过询问存储库是否已经存在具有该 ID/名称的用户来检查用户是否已经存在。为此,您需要在您的存储库中使用一个名为 bool UserAlreadyExists(User user)
的方法。
@Munish Goyal,不,这是不正确的。抽象的 UserRepository、User 类和 UserService 必须在同一个程序集 (AssemblyA) 中。存储库的不同实现可以在它们自己的程序集中(AssemblyB/C)。使用 UserService 的程序需要同时引用 AssemblyA 和 AssemblyB(或 AssemblyC)。以上是关于如何适当地设计数据访问层?的主要内容,如果未能解决你的问题,请参考以下文章