Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我的Mapper类应该被注入到我的控制器中,还是可以直接实例化它?_C#_Asp.net Mvc_Dependency Injection_Mapping_Solid Principles - Fatal编程技术网

C# 我的Mapper类应该被注入到我的控制器中,还是可以直接实例化它?

C# 我的Mapper类应该被注入到我的控制器中,还是可以直接实例化它?,c#,asp.net-mvc,dependency-injection,mapping,solid-principles,C#,Asp.net Mvc,Dependency Injection,Mapping,Solid Principles,在我的控制器中,所有依赖项都是通过注入接收的,除了一个由构造函数实例化的Mapper类之外: 公共类HomeController:控制器 { 私有只读应用服务SomeAppService; 私有只读映射器映射器; 公共家庭控制器(ISomeAppService someAppService) { SomeAppService=SomeAppService; 映射器=新映射器(); } 公共行动结果索引() { var someList=SomeAppService.GetSomeList();

在我的控制器中,所有依赖项都是通过注入接收的,除了一个由构造函数实例化的Mapper类之外:

公共类HomeController:控制器
{
私有只读应用服务SomeAppService;
私有只读映射器映射器;
公共家庭控制器(ISomeAppService someAppService)
{
SomeAppService=SomeAppService;
映射器=新映射器();
}
公共行动结果索引()
{
var someList=SomeAppService.GetSomeList();
var someListDTO=Mapper.Map(someList);
返回视图(新的HomeIndexViewModel(someListDTO));
}
SomeAppService
是我的域层前面的应用层服务。映射器接收域对象并返回视图要使用的DTO

我的理由是,由于a,我无法预见我需要用其他东西替换映射器的任何情况,或者这对测试有何不利。我也无法看到这个映射器类在任何其他表示层上被重用,因为其他视图可能与Web表示不同。对我来说,它感觉是控制器的一部分


问题是,这是否正确?我是否需要通过依赖项注入来接收映射器?我是否需要为它定义一个接口?如果需要,原因是什么?我想坚持坚实的原则,但我想知道它们是否以及如何在这里应用。

我个人建议注入你的映射器实例。这正是IoC所需要的tainer设计用于管理

没有理由在您的控制器中实例化它,它的当前状态违反了打开-关闭原则和实体原则的控制反转

使用IoC容器注入时,您将获得以下好处:

改进的可测试性

通过将映射器实例注入控制器,您将能够为其创建模拟以编写更好的测试。虽然您可以像现在这样测试控制器,但您无法在控制器内测试映射器实例的任何条件

改进的扩展性

如果您希望能够将构造函数参数传递到映射器中,几个月后会发生什么情况?您需要完成所有控制器操作并更新构造函数。通过将创建映射器实例的责任传递给IoC容器,您正在创建单个配置点,这意味着任何进一步的对映射器类的修改或更改可以在一个位置进行管理和配置


对于大多数预期寿命超过几个月的软件,有一件事是可以确定的,那就是它会发生变化。虽然您现在可能看不到更改mapper实例的原因,但最好的做法是以一种使您能够尽可能轻松地进行更改的方式设计软件。您需要更改的零碎部分越多e、 最有可能的情况是您破坏了某些东西或引入了一个bug。

除了上述@JoeMighty提供的所有好处之外,我还要补充一点,通过在控制器中注入映射器,您可以将Mapper.Map定义外部化,免除控制器的责任。此外,您还可以通过控制注入映射器的生命周期,因此映射器不必在每个请求上创建定义。

考虑这一点的一种方法是问问自己在SAN Mapper类中做什么。大多数人编写一个私有函数来完成这项工作,或者如果对象足够简单,他们只需重新创建它并内联进行映射。然而,reason这种特殊情况看起来很可疑,因为您的类被称为“Mapper”,不接受任何特定的初始化(指示它映射对象)所以我只能假设它有能力映射所有类型的对象,可能是一些与此控制器无关的对象。这可能是它感觉有点臭的原因。谢谢你的回答。我从来没有想到我可能需要在某个时候将参数传递给映射器,这是一个很好的例子。我一定会将它注入我的控制器。有一件事我不太清楚,您所说的“现在,您无法在控制器内测试mapper实例的任何条件”是什么意思?很好!你还没有足够的代表来编辑帖子吗?很公平:)来回答你的问题-由于你的mapper实例是在你的控制器内部实例化的,而不是注入的,你无法模拟它;因此,例如,你将无法模拟它来编写一个单元测试来测试你的控制器如何处理
mapper.Map
返回空引用。