.NET核心分层服务中的依赖注入

时间:2019-09-16 12:52:36

标签: asp.net asp.net-core dependency-injection inversion-of-control repository-pattern

我正在尝试学习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语句呢?我将如何处理?有人遇到过我遇到的类似问题吗?您是否认为还有另一种更好的系统架构方法?

谢谢你,祝你有美好的一天

1 个答案:

答案 0 :(得分:0)

您的问题尚不清楚,但通常来说,您的存储库/工作单元应实现一个接口。然后,您只需注入接口。然后,您可以为ConfigureServices中的那些接口使用不同的实现方式。

但是,这里有一些关键问题。首先,请勿将您的EF Core上下文包装在工作库/工作单元中。 EF是ORM,因此,它已经已经实现了存储库(DbSet)和工作单元(DbContext)模式。如果要将您自己的存储库和工作单元作为自然的结论,并实现所有可能的功能,那么您仅需重新创建EF就不会做任何事情。当您使用诸如EF之类的ORM时,实际上您是在选择使用第三方DAL,因此,除了此以外,再创建自己的DAL层是没有意义的。

您可能会争辩说,您仍然想要基于EF的抽象,但是您已经在服务类中拥有了它。这些应该直接利用您的上下文,并且存储库和工作单元应该放在垃圾箱中。

第二,看到类似public AssetService(GcgcUnitOfWork uow, LandornetUnitOfWork uow2)之类的内容立即告诉我,该类已损坏。一个工作单元应该封装一个完整的子域,如果您要注入其中的两个子域,则意味着您的服务类正在使用两个不同的子域,因此做得太多。一个班级应该只做一件事并且做好。