Juile Lerman的多元化课程“EF in Enterprise”让我印象深刻,并决定构建我的演示应用程序。在应用SOLID原则时需要帮助
我正在使用VS 2012和最新版本的EF,SQL Server和MVC。我正在构建一个应用SOLID原则的演示应用程序。我正在这样做,以更好地了解如何执行单元测试。
我对这个演示应用程序使用了DB第一种方法。它只包含一个名为UserDetails的表,下面是它在SQL服务器中的外观。我将使用此表进行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解决方案:此层包含我的域类(或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交换。我如何实现这一目标?
感谢您阅读这个大问题,我真的很感激,如果任何人都可以指向正确的方向。
'IRepository'不应该返回'IQueryable'类型。请,[看到这个链接](https://stackoverflow.com/questions/33755499/entity-framework-repository-pattern-why-not-return-iqueryable) – StepUp