我正在尝试学习IoC和DI,并将其并入Asp.NET Core上的分层webapi项目中,以便可以使用SQLite内存数据库伪造数据库上下文并测试服务层的行为。 / p>
我有一些unitOfWorks,每个都包含存储库。每个数据库一个工作单元。其中之一如下所示:
public class GcgcUnitOfWork : IDisposable
{
private readonly GcgcContext _context;
public AssetRepository assetRepository;
public GcgcUnitOfWork(GcgcContext context)
{
_context = context;
assetRepository = new AssetRepository(_context);
}
public int Complete()
{
try
{
return _context.SaveChanges();
}
catch (Exception ex)
{
return 0;
}
}
public void Dispose()
{
_context.Dispose();
}
}
在我的服务层上,我使用这些工作单位。一些服务类与两个不同的工作单元交互。如下所示:
public class GcgcService : IGcgcService
{
public GcgcAssetDataDTO GetGcgcAssetData()
{
using (var uow = new GcgcUnitOfWork())
using (var uowLandornet = new LandornetUnitOfWork())
{
var result = new GcgcAssetDataDTO();
/**do something.*/
return result;
}
}
}
但是现在,为了测试服务层的行为,我需要将带有db上下文的存储库注入服务层构造函数。所以我需要更改为以下内容:
public class AssetService
{
GcgcUnitOfWork _uow;
LandornetUnitOfWork _uow2;
public AssetService(GcgcUnitOfWork uow, LandornetUnitOfWork uow2)
{
_uow = uow;
_uow2 = uow2;
}
public List<GcgcAsset> GetAssets()
{
return _uow.assetRepository.GetAssets();
}
/*also use and interact with other service classes that use these unit of works as well*/
}
因此,在我的测试项目中,我可以使用内存数据库db上下文的工作单元实例化服务类。但是using语句呢?我将如何处理?有人遇到过我遇到的类似问题吗?您是否认为还有另一种更好的系统架构方法?
谢谢你,祝你有美好的一天
答案 0 :(得分:0)
您的问题尚不清楚,但通常来说,您的存储库/工作单元应实现一个接口。然后,您只需注入接口。然后,您可以为ConfigureServices
中的那些接口使用不同的实现方式。
但是,这里有一些关键问题。首先,请勿将您的EF Core上下文包装在工作库/工作单元中。 EF是ORM,因此,它已经已经实现了存储库(DbSet
)和工作单元(DbContext
)模式。如果要将您自己的存储库和工作单元作为自然的结论,并实现所有可能的功能,那么您仅需重新创建EF就不会做任何事情。当您使用诸如EF之类的ORM时,实际上您是在选择使用第三方DAL,因此,除了此以外,再创建自己的DAL层是没有意义的。
您可能会争辩说,您仍然想要基于EF的抽象,但是您已经在服务类中拥有了它。这些应该直接利用您的上下文,并且存储库和工作单元应该放在垃圾箱中。
第二,看到类似public AssetService(GcgcUnitOfWork uow, LandornetUnitOfWork uow2)
之类的内容立即告诉我,该类已损坏。一个工作单元应该封装一个完整的子域,如果您要注入其中的两个子域,则意味着您的服务类正在使用两个不同的子域,因此做得太多。一个班级应该只做一件事并且做好。