加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 需要帮助来应用SOLID原则

发布时间:2020-12-16 06:27:00 所属栏目:asp.Net 来源:网络整理
导读:Juile Lerman关于“企业中的EF”的多元化课程给我留下了深刻的印象,并决定构建我的演示应用程序. 我正在使用VS 2012和最新版本的EF,SQL Server和MVC.我正在构建一个应用SOLID原则的演示应用程序.我这样做是为了更好地理解如何实现DI单元测试. 我在这个演示应
Juile Lerman关于“企业中的EF”的多元化课程给我留下了深刻的印象,并决定构建我的演示应用程序.

我正在使用VS 2012和最新版本的EF,SQL Server和MVC.我正在构建一个应用SOLID原则的演示应用程序.我这样做是为了更好地理解如何实现DI&单元测试.

我在这个演示应用程序中使用了DB first方法.它只包含一个名为UserDetails的表,下面是它在SQL Server中的外观.我将使用此表进行CRUD操作.

以下是我如何分层我的应用程序:

1. WESModel解决方案:该层包含我的Model1.edmx文件和上下文类,如下所示.

namespace WESModel
{
    using System;
    using System.Data.Entity;
    using System.Data.Entity.Infrastructure;
    using WESDomain;

    public partial class WESMVCEntities : DbContext
    {
        public WESMVCEntities()
            : base("name=WESMVCEntities")
        {
        }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            throw new UnintentionalCodeFirstException();
        }

        public DbSet<UserDetail> UserDetails { get; set; }
    }
}

2. WESDomain解决方案:该层包含我的Domain类(或POCO类).这些POCO类实际上是在我的WESModel层中自动生成的.我把它们移到了这一层.以下是单个POCO类的外观.

namespace WESDomain
{
    using System;
    using System.Collections.Generic;

    public partial class UserDetail:IUserDetail
    {
        public int Id { get; set; }
        public string UserName { get; set; }
    }
}

3:WESDataLayer解决方案:该层包含对上述2层dll的引用.
该层具有我的Repository类,如下所示.现在,我将IRepository保持在同一个类:)

namespace WESDataLayer
{ 
    public class UserDetailRepository : IUserDetailRepository
    {
        WESMVCEntities context = new WESMVCEntities();

        public IQueryable<IUserDetail> All
        {
            get { return context.UserDetails; }
        }

        public IQueryable<IUserDetail> AllIncluding(params Expression<Func<IUserDetail,object>>[] includeProperties)
        {
            IQueryable<IUserDetail> query = context.UserDetails;
            foreach (var includeProperty in includeProperties) {
                query = query.Include(includeProperty);
            }
            return query;
        }

        public IUserDetail Find(int id)
        {
            return context.UserDetails.Find(id);
        }

        public void InsertOrUpdate(UserDetail userdetail)
        {
            if (userdetail.Id == default(int)) {
                // New entity
                context.UserDetails.Add(userdetail);
            } else {
                // Existing entity
                context.Entry(userdetail).State = EntityState.Modified;
            }
        }

        public void Delete(int id)
        {
            var userdetail = context.UserDetails.Find(id);
            context.UserDetails.Remove(userdetail);
        }

        public void Save()
        {
            context.SaveChanges();
        }

        public void Dispose() 
        {
            context.Dispose();
        }
    }

    public interface IUserDetailRepository : IDisposable
    {
        IQueryable<IUserDetail> All { get; }
        IQueryable<IUserDetail> AllIncluding(params Expression<Func<UserDetail,object>>[] includeProperties);
        UserDetail Find(int id);
        void InsertOrUpdate(UserDetail userdetail);
        void Delete(int id);
        void Save();
    }
}

4:ConsoleApplication1解决方案:这是我的UI层.它将是我最终应用程序中的MVC应用程序.在这里,我只是查询数据库并显示数据.这就是代码的外观.

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
             IUserDetailRepository repo = new UserDetailRepository();

             var count = repo.All.ToList().Count().ToString();
             Console.WriteLine("Count: {0}",count);
             Console.ReadLine();

        }
    }
}

问题:我的UI层没有任何引用EF DLL.但是,它有一个Repository类的实例.在MVC应用程序中,我的控制器将具有存储库类或UnitOfWork的实例.

a)这是正确的做法吗?

b)有什么办法可以抽象出来吗?

c)如果将来我想用Dapper或任何其他ORM工具换掉EF怎么办?

d)我如何在我的项目中使用我的DI工具?它应该在哪一层?

e)单元测试.我知道StructureMap,并希望在这个项目中使用它,以便将来我应该能够与Ninject交换它.我如何实现这一目标?

感谢您阅读这个大问题,如果有人能指出我正确的方向,我真的很感激.

解决方法

Question: My UI layer does not have any ref to EF DLL. However,It has
an instance of Repository class. In MVC application,my controller
will have an instance of repository class or UnitOfWork.

是的,UI图层类不能对EF有任何引用.但要做到这一点,他们不能引用具体的存储库.在MVC应用程序中,如果您不使用服务层,Controller将只在IUserDetailRepository上有一个引用,并等待构造中的具体类型.
关于UnitOfWork,这取决于你的实现:-)

a) Is this the right thing to do ?

正确的做法是称为“松耦合”,似乎你的设计就是选择这种方式.

b) Is there any way i can abstract it ?

是的,您可以使用依赖性解析程序.这样,无需引用具体类型,您将只有基于抽象的代码

c) What if in future i want to swap out EF with Dapper or any other ORM tool ?

您必须具有数据访问层,例如,包含IXxxRepository契约的具体实现的库.在您的情况下,它将是EF实现.当您为Dapper进行更改时,您将不得不重新实现此图层.重构有一个可接受的限制.

d) How do i fit my DI tool in this project ? In which layer it should be ?

放置DI工具的最佳位置是UI层.在应用程序启动时,您将配置依赖项绑定,一切都将自动运行;)

e) Unit testing. I am aware of StructureMap and want to make use of it in this project in such a way that in future i should be able to swap it out with Ninject. How do i achieve this ?

你想拔下你的Dependency Resolver插上另一个吗?没问题,只需在编码DR的配置时进行预测,以便与您的应用程序保持最小耦合.在某些情况下,有一些限制耦合的技巧……在我目前正在开发的项目中,我们首先有一个MVC应用程序和一个服务层,业务层,数据访问层和基础设施层.我们使用Ninject作为DR,并且基础结构和Web UI层是唯一具有Ninject参考的层.拔掉它很容易,我们已经用这种方式尝试过Unity.

还有一件事,你不应该有UserDetail的合同.没有必要,在无状态类上使用依赖注入,而不是在DTO之类的所有类上使用依赖注入.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读