1
|
Erçin DedeoÄlu · 技术社区 · 6 年前 |
![]() |
1
138
我用
并从任何在DI注册的类中使用,例如:
更新 请记住,在这个例子中,解析的关键是一个字符串,为了简单起见,因为op特别要求这个例子。 但是,您可以使用任何自定义的解析类型作为键,因为您通常不希望大型n-case开关损坏您的代码。取决于你的应用程序的扩展方式。 |
![]() |
2
58
另一种选择是使用扩展方法
将您的服务注册为:
然后用一点林肯的话解决:
或
(假设
一定要有
更新
ASPNET 2.1来源:
|
![]() |
3
15
它不受
但是您可以插入另一个依赖注入机制,比如
一点也不难:
就这样。 对于要构建的示例,您需要
|
![]() |
4
11
我也遇到过同样的问题,我想和大家分享我是如何解决这个问题的。 正如你提到的,有两个问题。 第一个:
我们有什么选择?人们建议两个:
事实上,这两个选项都是工厂,因为每个ioc容器也是一个工厂(但高度可配置且复杂)。在我看来,其他的选择也是工厂模式的变化。 那么,还有什么更好的选择呢?这里我同意@sock建议使用定制工厂,这就是原因。 首先,当不需要新的依赖项时,我总是尽量避免添加它们。所以我同意你的观点。此外,使用两个di框架比创建自定义工厂抽象更糟糕。在第二种情况下,您必须添加新的包依赖项(如unity),但依赖于新的工厂接口在这里并不那么糟糕。我相信,asp.net core di的主要思想是简单。它维护了一组最少的特性 KISS principle . 如果你需要一些额外的功能,那么自己动手或使用相应的 Plungin 实现所需功能(开闭原理)的。
其次,通常我们需要为单个服务注入许多命名依赖项。在统一的情况下,您可能需要为构造函数参数指定名称(使用
第二个问题:
首先,我同意你的看法
为此,asp.net core di提供了一个非常好的重载:
|
![]() |
5
10
没错,内置的asp.net核心容器没有注册多个服务然后检索特定服务的概念,正如您所建议的,在这种情况下,工厂是唯一真正的解决方案。 或者,您可以切换到第三方容器,如Unity或StructureMap,它确实提供了您需要的解决方案(在这里记录: https://docs.asp.net/en/latest/fundamentals/dependency-injection.html?#replacing-the-default-services-container ) |
![]() |
6
6
我只是简单地注射了 在startup.cs中配置服务
服务文件夹
Mycontroller.cs公司
扩展.cs
|
![]() |
7
4
显然,你可以注入你的服务接口的IEnumerable! 然后使用linq找到您想要的实例。 我的示例是aws sns服务,但是您可以对任何注入的服务执行同样的操作。 启动
snsconfig公司
appsettings.json设置
SNS工厂
现在,您可以在自定义服务或控制器中获取所需区域的sns服务
|
![]() |
8
2
虽然看起来“米格尔A.阿里拉已经清楚地指出了这一点,我投了他的票,但我在他有用的解决方案的基础上创造了另一个解决方案,看起来很整洁,但需要做更多的工作。
这完全取决于上述解决方案。所以基本上我创造了类似于
服务访问器如下所示:
最终结果是,您将能够使用名称或命名实例注册服务,就像我们以前对其他容器所做的那样..例如:
现在这已经足够了,但是为了使您的工作完成,最好添加更多的扩展方法,以便按照相同的方法覆盖所有类型的注册。 stackoverflow上还有一个帖子,但我找不到,海报详细解释了为什么不支持这个功能,以及如何解决它,基本上类似于@miguel所说的。这是一个不错的帖子,尽管我不同意每一点,因为我认为有些情况下,你真的需要命名的实例。一旦我再找到这个链接,我会把它贴在这里。 实际上,您不需要传递选择器或访问器: 我在我的项目中使用了以下代码,到目前为止效果良好。
|
|
9
2
这次聚会有点晚了,但我的解决办法是:… startup.cs或program.cs如果是通用处理程序…
T接口设置界面
t接口的具体实现
希望如果这样做有什么问题,有人会善意地指出为什么这样做是错误的。 |
|
10
1
工厂的方法当然是可行的。另一种方法是使用继承创建从iSeries设备继承的单个接口,在iSeries设备实现中实现继承的接口,并注册继承的接口而不是基接口。添加继承层次结构还是工厂是“正确的”模式都取决于您与谁交谈。在处理同一应用程序中使用泛型的多个数据库提供程序时,我经常必须使用此模式,例如
接口和实现示例:
容器:
|
![]() |
11
1
我的解决方案是什么值得…考虑转投温莎城堡,因为我不喜欢上面的任何解决方案。对不起的!!
创建各种实现
登记处
构造函数和实例用法…
|
![]() |
12
1
巫术。
然后向服务集合注册字典:
如果您不愿意获取字典并按键访问它,则可以通过向服务集合添加其他键查找方法来隐藏字典:
现在您可以使用
或
正如我们所看到的,第一个完全是多余的,因为你也可以用字典来完成,而不需要闭包和addtransient(如果你使用vb,连大括号都不一样):
(更简单更好-但您可能希望将其用作扩展方法)
当然,如果你不喜欢字典,你也可以在你的界面上设置一个属性
但这需要更改接口以适应该属性,并且通过许多元素的循环应该比关联数组查找(dictionary)慢得多。
这些只是我的0.05美元 |
![]() |
13
0
虽然开箱即用的实现不提供它,但这里有一个示例项目,它允许您注册命名实例,然后将inamedservicefactory注入到代码中,并按名称拉出实例。与这里的其他facury解决方案不同,它允许您注册 相同的实现 但配置不同 |
![]() |
14
0
服务换服务怎么样? 如果我们有一个inamedservice接口(具有.name属性),我们可以为.getservice(string name)编写一个iservicecollection扩展,扩展将接受该string参数,并对其本身执行.getservices()操作,在每个返回的实例中,找到其inamedservice.name的实例匹配给定的名称。 这样地:
因此,您的imyservice必须实现inamedservice,但您将获得所需的基于密钥的解决方案,对吗? 公平地说,甚至必须拥有这个inamedservice接口看起来也很难看,但是如果您想更进一步,使事情变得更优雅,那么在这个扩展中的代码可以找到实现/类上的[namedserviceattribute(“a”)],它也能正常工作。更公平地说,反射是缓慢的,因此优化可能是有序的,但老实说,这是di引擎应该帮助的。速度和简单性是TCO的两大贡献因素。 总之,不需要显式工厂,因为“查找命名服务”是一个可重用的概念,工厂类不作为解决方案进行扩展。一个func<>看起来不错,但是一个switch block是这样的 布雷 ,同样,您将像编写工厂一样频繁地编写函数。从简单的、可重用的、更少的代码开始,如果结果不是为了你,那么就变得复杂。 |
![]() |
15
0
扩展@rnrneverdies的解决方案。除了tostring(),还可以使用以下选项-1)公共属性实现,2)由@craig brunetti建议的服务服务。
|