通过简单注入器传递带有变量的类

本文关键字:变量 简单 注入器 | 更新日期: 2023-09-27 18:03:50

尝试自学SimpleInjector和我掌握的基础知识,但需要一些帮助。

本质上,我想通过一个简单的注入器传递一个我已经填充过的对象,而不是一个新对象。

我的例子如下:

ITeaService:

    public interface ICup
{
    string CupName { get; set; }
    List<string> Ingredients { get; set; }
}
public class Cup : ICup
{
    public string CupName { get; set; }
    public List<string> Ingredients { get; set; }
}
public interface ITeaService
{
    ICup GetTea();
}

TeaService:

    public class TeaService : ITeaService
{
    private ICup _cup;
    public TeaService(ICup cup)
    {
        _cup = cup;
    }
    public ICup GetTea()
    {
        this._cup.Ingredients.Add("Tea bag");
        this._cup.Ingredients.Add("Hot water");
        return this._cup;
    }
}
测试:

 var container = new SimpleInjector.Container();
        container.Register<ITeaService, TeaService>();
        container.Register<ICup, Cup>();
        container.Verify();
        // Act
        var cp = container.GetInstance<ICup>();
        cp.CupName = "Daniel";

        var teaService = container.GetInstance<ITeaService>();
        var cup = teaService.GetTea();

有什么想法我如何通过一个预定义的杯子?变量cp在哪里我已经指定了一个CupName?

通过简单注入器传递带有变量的类

下面一行是错误的:

container.Register<ICup, Cup>();

在这里,你告诉SimpleInjector在ICup被请求时创建一个新的Cup。将其更改为以下内容,以始终返回相同的Cup:

var standardCup = new Cup();
standardCup .CupName = "Daniel";
container.RegisterSingleton<ICup>(standardCup );

现在测试成功了:

var teaService = container.GetInstance<ITeaService>();
var cup = teaService.GetTea();
Assert.AreEqual(cup.CupName, "Daniel");
Assert.AreEqual(cup, standardCup);

编辑:基于注释:如果你总是想要一个新的实例,但具有相同的名称,你可以这样做:

container.Register<ICup>(() => new Cup { CupName = "Daniel"});

这将运行回调来构建一个Cup每次您请求一个ICup

你的第一个问题是你实际上在测试什么?

你写测试的方式是测试SimpleInjector是否工作,而不是你的代码是否工作。

你需要一个使用类来实现接口的测试,因为你需要真正的代码来测试任何东西。

我要做的是:

  1. 创建一个实现ICup的Cup类——你可能已经有了。
  2. 创建它的一个实例,并通过服务类的构造函数传递它。
  3. 测试您期望的输出是否正确。

你真的希望你的测试是有价值的,并且测试真正的功能,而不是DI和IOC,它们无论如何都能保证工作。

有道理吗?您正在测试Cup类,更有可能是服务类,它们是真正的类,而不是它们的抽象,根据定义,它们没有功能,因此没有什么可测试的。

想象一下当你有两个实现ICup的类时会发生什么。您将编写两个测试类,每个实现一个。

基于注释

添加更多细节

你的测试就简单多了。

您所要做的就是测试一旦添加了一个成分,它是否实际出现在Cup对象的Ingredients列表中。这意味着您只需要测试Cup类,服务在此时不为您做任何事情。尽可能测试最简单的交互,一旦这些有效,你就可以一步一步地继续进行更复杂的事情。

因此编写CupTests类。测试当你添加一个成分时,它实际上出现在成分列表中,检查错误和边界错误,比如当你试图添加一些东西时,成分列表为空。

根据您目前所展示的,这就是您所需要的。

container.RegisterSingleton<ICup>(standardCup)在v5中已过时。

但是,您可以使用以下方式:

  container.RegisterInstance<ICup>(standardCup);