c# - 我应该在哪里存储对象集合以方便 DI/测试?

标签 c# dependency-injection factory-pattern

我试图弄清楚从数据库中检索到的应用程序运行所必需的对象集合的存储位置。例如,我正在尝试重新设计一个使用 Report 的报告应用程序和 Parameter对象。这些对象以 XML 格式存储在数据库中。在最简单的层面上,定义的集合可以存储为 Dictionary<string, string>。 (对象键、对象定义 XML)。

我想实现一个工厂模式来处理从它们的 XML 定义创建这些对象。

IReport GetReport(string reportName)
IParameter GetParameter(string parameterName)

这些方法要求工厂存储报告和参数的集合。

所以,我的问题是:

  1. 工厂应该完全存储对象集合还是只负责根据定义创建对象,将方法更改为 IReport GetReport(string reportDefinition)
  2. 如果工厂要存储对象,我是否应该简单地将集合注入(inject)到工厂类的构造函数中?
  3. 单元测试 - 如果我走 #2 的路线,我想我会直接将我的测试集合注入(inject)工厂,对吗?

最佳答案

您可以通过多种方式构建它,这些方式都遵循 SRP (Single Responsibility Principle) .

一种方法如下:有一个接口(interface),IReportLoadingService,带有一个接收报告标识符并返回IReport实例的方法。

这个 IReportLoadingService 的实现可以有一个 IReportDefinitionRetrievalService 作为依赖,例如

public class ReportLoadingService : IReportLoadingService
{
    private readonly IReportDefinitionRetrievalService _definitionService;

    public ReportLoadingService(IReportDefinitionRetrievalService definitionService)
    {
        _definitionService = definitionService;
    }

    public IReport GetReport(string reportName)
    {
        var reportDefinition = definitionService.GetDefinition(reportName);
        return GenerateReportFromDefinition(reportDefinition);
    }

    private IReport GenerateReportFromDefinition(string definition)
    {
        // Logic to construct an IReport implementation
    }

}

IReportDefinitionRetrievalService 的实时实现将访问数据库并返回 XML。现在您的 ReportLoadingService 负责填充 IReport 实例,而另一个服务负责实际获取报告定义。

对于单元测试,您可以创建一个 IReportDefinitionRetrievalService 的 Mock,它可以执行您想要的任何操作(例如,在字典中查找定义)。看看Moq一个好的模拟框架。它将允许你做这样的事情:

[Test]
public void GetReportUsesDefinitionService()
{
    var mockDefinitionService = new Mock<IReportDefinitionRetrievalService>();
    mockDefinitionService.Setup(s => s.GetDefinition("MyReportName")).Returns("MyReportDefinition");

    var loadingService = new ReportLoadingService(mockDefinitionService.Object);

    var reportInstance = loadingService.GetReport("MyReportName");

    // Check reportInstance for fields etc

    // Check the definition service was used to load the definition
    mockDefinitionService.Verify(s => s.GetDefinition("MyReportName"), Times.Once());
}

关于c# - 我应该在哪里存储对象集合以方便 DI/测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12007765/

相关文章:

c++ - DI Boost C++14 和动态容器

c# - 注册默认的 CaSTLe Windsor 组件,同时允许自定义组件

c++ - 从结构数据继承

c# - 使用反射转换为通用类型对象

c# - 使用 C# 验证 Google id token

java - 字段上的 CDI @Produces 注释的目的是什么?

Java工厂模式——动态加载类

c# - 从基类实例化派生类的通用工厂方法

c# - 服务器端分页和排序最佳实践?

c# - 在一个解决方案中调用来自不同项目的方法