Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Asp.net mvc ASP MVC应用程序的存储库模式设计_Asp.net Mvc_Design Patterns_Architecture_Repository Pattern_Data Access Layer - Fatal编程技术网

Asp.net mvc ASP MVC应用程序的存储库模式设计

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

这更多的是一个设计问题

我正在构建一个应用程序,我已经创建了我的存储库模式结构,如下所示:

我的核心名称空间是DAL/Repository/BusinessLogicLayers组件

顺便说一句,我正在使用Dapper.NET micro ORM作为数据连接,这就是为什么您会在我的SqlConnection对象上看到一个扩展

对于我的数据访问,我创建了一个基本存储库类:

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)

有了这个