Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/307.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# 在Unity中解析类型时传递构造函数参数:最佳实践_C#_.net_Dependency Injection_Unity Container - Fatal编程技术网

C# 在Unity中解析类型时传递构造函数参数:最佳实践

C# 在Unity中解析类型时传递构造函数参数:最佳实践,c#,.net,dependency-injection,unity-container,C#,.net,Dependency Injection,Unity Container,当使用依赖项注入来提供要在构造函数中使用的参数时,有时是必要的。Unity(和其他依赖项注入容器)支持这一点,因此当它尝试创建该类型的实例时,它可以在构造函数中提供参数作为参数 我的问题是:这种方法可取吗 在接口中,无法指定实现类必须具有哪些参数。通过将参数指定给Unity,可以假定实现类具有这些参数,并且可以对未来的实现类放置隐式约束。这些约束不能通过接口进行通信 那么,这是否就是接口本身的指定方式(在.NET中)的缺陷,例如,是否可以指定构造函数签名?或者这个特性(能够提供构造函数参数)是否

当使用依赖项注入来提供要在构造函数中使用的参数时,有时是必要的。Unity(和其他依赖项注入容器)支持这一点,因此当它尝试创建该类型的实例时,它可以在构造函数中提供参数作为参数

我的问题是:这种方法可取吗

在接口中,无法指定实现类必须具有哪些参数。通过将参数指定给Unity,可以假定实现类具有这些参数,并且可以对未来的实现类放置隐式约束。这些约束不能通过接口进行通信

那么,这是否就是接口本身的指定方式(在.NET中)的缺陷,例如,是否可以指定构造函数签名?或者这个特性(能够提供构造函数参数)是否由于其他需要而包含在Unity中

唯一切实可行的方法(对我来说)似乎是使用工厂来创建实现类,并在工厂上进行依赖项注入

我明白我在这里的问题可能不清楚,所以我将以稍微不同的方式提问:对于一个构造函数需要参数的类,进行依赖项注入的最佳方式是什么

(我不认为这个问题是主观的,因为这种依赖注入可能应该有一个单一的设计模式。)

编辑:


我应该补充一点,我的主要问题是我可能会创建一个新的实现类,它有额外的构造函数参数(其中构造函数参数不是unity可以创建的)。

IoC容器(比如unity)的责任是将接口与具体实现连接起来。这意味着您的容器必须知道接口以及如何创建实现接口的对象。使用构造函数注入是完全合法的,也是推荐的方法。当应用程序通过Resolve()方法请求接口时,Unity将创建具体的实现。
Unity容器本身就是创建对象的工厂,您使用Unity是因为您不想自己实现这些工厂。

我不确定您是从哪里想到构造函数注入不适合DI的。我要说的是,实际情况与此相反:构造函数注入是用于实现依赖项注入的最常见的模式之一——我甚至要说它是最常见的模式,而且这种观点肯定得到了大多数控制反转容器(DI容器)的支持使用构造函数注入作为首选机制

例如,StructureMap有一个核心的、非常具体的构造函数注入支持,它将选择参数最多的构造函数作为用于依赖项解析的构造函数

通过使用构造函数注入模式,您所说的是“我通过将硬编码依赖项指定为传递到构造函数中的参数来删除类中的依赖项-没有这些依赖项,我的类无法实例化”。当然,该语句的前半部分是DI的精髓,但后半部分更强调这一点

依赖关系是一种实现细节,应该能够轻松更改,从而提供灵活、松散耦合的解决方案。他们关注的是如何,而不是什么。接口指定了什么。所以我想说,您关于在接口中指定依赖项的建议实际上违背了依赖项注入的概念

至于你关于工厂的陈述——这正是IOC容器的含义——处理解决方案依赖关系树的大型工厂,所以你不需要在意

编辑

我想您可能在问这样一种情况,您希望提供一个非依赖构造函数参数,例如引用实体的id或初始状态枚举


我个人认为IOC容器允许这样做没有问题。它仍然是类的初始状态,因此需要显式表示创建该状态的规则。这可能意味着您有时需要更多地引用您可能喜欢的IOC容器,但这还不足以让您放弃Constructor注入的其他好处。

这里的问题是Unity中的注入构造函数与Castle.Windsor中的注入构造函数的定义

在Unity中,如果您需要注入一个特定的参数,比如一个AppSetting,那么您还必须提供所有其他参数,从而修复构造函数的签名。但是,在Castle.Windsor中,它接受您提供的参数,然后使用解析机制以正常方式定位其他参数


通过编写一个“最佳匹配”的定制构建器策略,将这一点引入Unity是可能的使用哪个构造函数而不是默认的贪婪/提供所有默认值。

您的编辑是正确的-我指的是构造函数中的参数,这些参数是特定的类实例或值类型,IOC容器不会通过创建新实例来解决这些问题,但是如果构造函数需要实例变量,我需要自己提供给Unity。但是接口没有指定我需要这些参数,所以如果我创建一个接口的具体实现,该实现在构造函数中有额外的参数,该怎么办?