gpt4 book ai didi

asp.net-mvc - 在应用 SOLID 原则时需要帮助

转载 作者:行者123 更新时间:2023-12-05 01:07:51 26 4
gpt4 key购买 nike

关闭。这个问题是opinion-based .它目前不接受答案。












想改进这个问题?更新问题,以便 editing this post 可以用事实和引用来回答它.

1年前关闭。




Improve this question




Juile Lerman 的“EF in Enterprise”类(class)给我留下了深刻的印象,并决定构建我的演示应用程序。

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

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

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

1、WES模型解决方案:该层包含我的 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 解决方案:该层包含我的域类(或 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解决方案:这一层包含对我上面两层的 dll 的引用。
这一层有我的存储库类,如下所示。现在,我将 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 应用程序中,我的 Controller 将具有存储库类或 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 ?



是的,您可以使用 Dependency Resolver。这样,无需引用具体类型,您将拥有仅基于抽象的代码

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 层。在应用程序启动时,您将配置依赖项绑定(bind),一切都会自动运行;)

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 ?



你想拔掉你的依赖解析器来插入另一个?没问题,只需在对 DR 的配置进行编码时进行预测,以使与您的应用程序的耦合最小。在某些情况下有一些限制耦合的技巧……在我目前正在从事的项目中,我们首先有一个 MVC 应用程序和一个服务层、业务层、数据访问层和基础设施层。我们使用 Ninject 作为 DR,基础设施和 Web UI 层是唯一对 Ninject 有引用的层。拔掉它很容易,我们已经用这种方式尝试过 Unity。

还有一件事,您不应该与 UserDetail 签订契约(Contract)。没有必要,在无状态类而不是像 DTO 这样的所有类上使用依赖注入(inject)。

关于asp.net-mvc - 在应用 SOLID 原则时需要帮助,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17898906/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com