通过简单注入器传递带有变量的类
本文关键字:变量 简单 注入器 | 更新日期: 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是否工作,而不是你的代码是否工作。
你需要一个使用类来实现接口的测试,因为你需要真正的代码来测试任何东西。
我要做的是:
- 创建一个实现ICup的Cup类——你可能已经有了。
- 创建它的一个实例,并通过服务类的构造函数传递它。
- 测试您期望的输出是否正确。
你真的希望你的测试是有价值的,并且测试真正的功能,而不是DI和IOC,它们无论如何都能保证工作。
有道理吗?您正在测试Cup类,更有可能是服务类,它们是真正的类,而不是它们的抽象,根据定义,它们没有功能,因此没有什么可测试的。
想象一下当你有两个实现ICup的类时会发生什么。您将编写两个测试类,每个实现一个。
基于注释
添加更多细节你的测试就简单多了。
您所要做的就是测试一旦添加了一个成分,它是否实际出现在Cup对象的Ingredients列表中。这意味着您只需要测试Cup类,服务在此时不为您做任何事情。尽可能测试最简单的交互,一旦这些有效,你就可以一步一步地继续进行更复杂的事情。
因此编写CupTests类。测试当你添加一个成分时,它实际上出现在成分列表中,检查错误和边界错误,比如当你试图添加一些东西时,成分列表为空。
根据您目前所展示的,这就是您所需要的。
container.RegisterSingleton<ICup>(standardCup)
在v5中已过时。
但是,您可以使用以下方式:
container.RegisterInstance<ICup>(standardCup);