Asp.net mvc ASP MVC应用程序的存储库模式设计
这更多的是一个设计问题 我正在构建一个应用程序,我已经创建了我的存储库模式结构,如下所示: 我的核心名称空间是DAL/Repository/BusinessLogicLayers组件 顺便说一句,我正在使用Dapper.NET micro ORM作为数据连接,这就是为什么您会在我的SqlConnection对象上看到一个扩展 对于我的数据访问,我创建了一个基本存储库类:Asp.net mvc ASP MVC应用程序的存储库模式设计,asp.net-mvc,design-patterns,architecture,repository-pattern,data-access-layer,Asp.net Mvc,Design Patterns,Architecture,Repository Pattern,Data Access Layer,这更多的是一个设计问题 我正在构建一个应用程序,我已经创建了我的存储库模式结构,如下所示: 我的核心名称空间是DAL/Repository/BusinessLogicLayers组件 顺便说一句,我正在使用Dapper.NET micro ORM作为数据连接,这就是为什么您会在我的SqlConnection对象上看到一个扩展 对于我的数据访问,我创建了一个基本存储库类: namespace Core { public class BaseRepository<T>: IDis
namespace Core
{
public class BaseRepository<T>: IDisposable where T : BaseEntity
{
protected SqlConnection conn = null;
#region Constructors
public BaseRepository() : this("LOCAL")
{
}
public BaseRepository(string configurationKey = "LOCAL")
{
conn = new SqlConnection(ConfigurationManager.ConnectionStrings[configurationKey].ConnectionString);
}
#endregion
#region IDisposable
public void Dispose()
{
conn.Dispose();
}
#endregion
/// <summary>
/// returns a list of entities
/// </summary>
/// <typeparam name="T">BaseEntity type</typeparam>
/// <param name="sproc">optional parameters, stored procedure name.</param>
/// <returns>BaseEntity</returns>
protected virtual IEnumerable<T> GetListEntity(string sproc = null)
{
string storedProcName = string.Empty;
if (sproc == null)
{
storedProcName = "[dbo].sp_GetList_" + typeof(T).ToString().Replace("Core.",string.Empty);
}
else
{
storedProcName = sproc;
}
IEnumerable<T> items = new List<T>();
try
{
conn.Open();
items = conn.Query<T>(storedProcName,
commandType: CommandType.StoredProcedure);
conn.Close();
}
finally
{
conn.Close();
}
return items;
}
}
}
名称空间核心
{
公共类BaseRepository:IDisposable其中T:BaseEntity
{
受保护的SqlConnection conn=null;
#区域构造函数
public BaseRepository():此(“本地”)
{
}
公共基本存储库(字符串configurationKey=“LOCAL”)
{
conn=新的SqlConnection(ConfigurationManager.ConnectionString[configurationKey].ConnectionString);
}
#端区
#可识别区域
公共空间处置()
{
conn.Dispose();
}
#端区
///
///返回实体列表
///
///基本实体类型
///可选参数,存储过程名称。
///基本实体
受保护的虚拟IEnumerable GetListenty(字符串存储过程=null)
{
string storedProcName=string.Empty;
if(存储过程==null)
{
storedProcName=“[dbo].sp_GetList_389;”+typeof(T).ToString().Replace(“Core.”,string.Empty);
}
其他的
{
storedProcName=存储过程;
}
IEnumerable items=新列表();
尝试
{
conn.Open();
items=conn.Query(storedProcName,
commandType:commandType.StoredProcess);
康涅狄格州关闭();
}
最后
{
康涅狄格州关闭();
}
退货项目;
}
}
}
对于我拥有的每个实体,比如ExtendeDeduser,消息,我创建了它的接口类对,如下所示:
namespace Core
{
public class ExtendedUserRepository : BaseRepository<UsersExtended>,IExtendedUserRepository
{
public ExtendedUserRepository() : this("PROD")
{
}
public ExtendedUserRepository(string configurationKey) : base(configurationKey)
{
}
public UsersExtended GetExtendedUser(string username)
{
var list = GetListEntity().SingleOrDefault(u => u.Username == username);
return list;
}
public UsersExtended GetExtendedUser(Guid userid)
{
throw new NotImplementedException();
}
public List<UsersExtended> GetListExtendedUser()
{
throw new NotImplementedException();
}
}
}
名称空间核心
{
公共类ExtendeDederRepository:BaseRepository,IExtendedUserRepository
{
public extendUserRepository():此(“产品”)
{
}
公共扩展存储库(字符串配置键):基本(配置键)
{
}
公共用户sextendender(字符串用户名)
{
var list=getListenty().SingleOrDefault(u=>u.Username==Username);
退货清单;
}
公共用户GetExtendeDeduser(Guid用户ID)
{
抛出新的NotImplementedException();
}
公共列表GetListExtendedUser()
{
抛出新的NotImplementedException();
}
}
}
等等
上面的代码只是其中一个实体:ExtendeDeduser
问题是:我应该为我拥有的每个实体创建一个接口类来实现接口对吗?或者我应该只有一个RepositoryClass和一个IRepository接口,其中包含来自所有实体的所有方法吗?我认为您不需要无缘无故地创建接口。我甚至不明白为什么这里需要基本存储库类。我甚至认为这不是存储库,而是DAL(数据访问层),但这是定义 我认为好的DAL实现应该将数据库结构与业务逻辑结构解耦,但硬编码sp_GetList_XXXEntityNameXXX模式或将存储过程名称传递到DAL之外并不是解耦 如果您认为所有实体列表都是以一种方式获得的,并且您总是需要业务逻辑中的完整实体集,而不需要任何参数,那么您会非常乐观,或者您的应用程序非常简单 只有当您计划替换/包装不同的实现,或者在一个类中混合几个接口时,才需要将接口与实现分离。否则不需要
创建存储库时不要考虑实体。存储库包含业务逻辑,应该根据使用场景构建。拥有像您这样的类更多的是关于数据访问层——DAL是在业务逻辑中需要的查询之上构建的。您可能永远不会同时需要所有用户的列表,但通常需要活动用户、特权用户等的列表 很难预测您将需要什么查询,所以我更喜欢从业务逻辑开始设计,顺便添加DAL方法 具有复杂域模型的系统通常受益于一个层,例如 由Data Mapper(165)提供,用于隔离域对象 来自数据库访问代码的详细信息。在这样的系统中,它可以是 值得在映射上构建另一层抽象 查询构造代码集中的层 使用通用存储库,您可以使用诸如
findBy(array('id'=>1))
,findOneBy(array('email'=>)之类的常用方法john@bar.com)
,findById()
,findAll()
等等。实际上,它只有一个接口
您必须始终创建一个具体的实现,该实现将指示存储库将管理的域对象,以便完成此任务getUsersRepository().findAll()
此外,如果需要更复杂的查询,可以在具体实现上创建新方法,例如findMostActiveUsers()
,然后在应用程序中重用它
现在,回答您的问题:
您的应用程序至少需要一个接口(即通用接口,带有通用方法)。但是,如果您设法使用特定的方法,比如我刚才提到的方法,那么最好使用另一个接口(例如RepositoryInterface和usersrepositoryinterface)
有了这个