gpt4 book ai didi

c# - 使用形式参数名称注入(inject)

转载 作者:太空宇宙 更新时间:2023-11-03 13:07:45 24 4
gpt4 key购买 nike

本题使用Unity语法,但适用于所有IOC容器。

如果我有一个需要十几个依赖项的构造函数,那没什么大不了的:

Container.RegisterType<ICustomerService, CustomerService>();

稍后我可能需要构造函数参数之一由命名实例填充。不幸的是,API 方法现在变得非常丑陋:

Container.RegisterType<ICustomerService, CustomerService>(new InjectionConstructor(
typeof(ICustomerRepository),
typeof(IEntityMapper),
typeof(IContext),
typeof(IOnboardingValidator),
typeof(ICustomerValidator),
typeof(ICustomerVerifier),
typeof(ICustomerHelper),
new ResolvedParameter<HttpClient>("producer"),
typeof(ILog)));

我可以通过在构造函数参数本身上放置一个 [Dependency("producer")] 注释来避免这种丑陋的冗长,但不幸的是,我的业务程序集将依赖于 Unity 库,这是我试图避免的。

如果有一种方法可以告诉 Unity(或 Autofac、Windsor、SimplerInjector、StructureMap 等)使用在构造函数中声明的正式参数名称“就好像”它代表要注入(inject)的命名实例,那将是完美的。如果形式参数名称与任何命名绑定(bind)都不匹配,那么它只是假定使用默认绑定(bind)。

像这样:

Container.RegisterType<ICustomerService, CustomerService>(new InjectionNameHandler());

也许这对于属性注入(inject)也有同样的作用。

上面假设的指令让我省去了必须指定构造函数的每个参数的工作,只需调整单个参数的分辨率。

假设我感兴趣的是具体类型中最长的构造函数,但这恰恰是它最有用的时候!

有没有办法在 Unity 2 中做到这一点?统一 3?或者任何其他 IOC 容器?

最佳答案

If I have a constructor that takes a dozen dependencies, it is no big deal

事实上,这是一件大事。具有许多依赖项的组件往往会违反 Single Responsibility Principle (建议零售价)。违反 SRP 会导致代码难以测试和维护。

如果您将代码重构为多个更简洁的类,问题可能不会完全消失,它已经不是什么问题了。

我认为您的代码是您违反单一职责原则的一个很好的例子。问题已经从类名开始:CustomerService。 “服务”后缀已经闻起来像违反了单一职责原则,Open/close Principle (OCP) 和 Interface Segregation Principle (ISP)给我。您很可能会违反 SRP,因为此类往往包含许多与客户相关的用例。按单个实体对事物进行分组并不能使其成为单一责任。您将违反 OCP,因为每次添加新的与客户相关的用例时,您都必须更改此类和接口(interface)。 ICustomerService 接口(interface)违反了 ISP,因为它有很多方法,而该接口(interface)的消费者只需要一两个,而不是全部。

除此之外,CustomerServices 类依赖于 ILogICustomerValidator 服务。这些似乎是横切关注点,主类不应该关注横切关注点。您应该使用面向方面的编程 (AOP) 技术(例如拦截或(最好)装饰)来应用横切关注点。

然而,这不可避免地会将您引向所描述的设计 herehere ,其中每个用例都有自己的类,并且所有用例都放在相同的通用单成员抽象之后。

Later I might need one of the constructor parameters to be filled by a named instance

虽然不是硬性规定,但根据我的经验,一个组件同时具有配置值和许多依赖项的情况并不常见。所以在这里您可能再次违反了 SRP,因为您可能想要抽象掉 producer 参数。

尤其是当您所说的HttpClient 是.NET 框架类型时,例如System.Net.Http.HttpClient。在这种情况下,您违反了 Dependency Inversion Principle (DIP)因为您不仅依赖于具体类型而不是抽象,它是一个框架组件,而且您的应用程序应该定义它需要的抽象。

因此,与其注入(inject) HttpClient,不如注入(inject)一个根据您的应用程序需求定制并遵循 SOLID 的服务。原则。这永远不能是框架组件,甚至不能是框架提供的抽象,因为这样的抽象仍然会违反 DIP 和 ISP。

关于c# - 使用形式参数名称注入(inject),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30180619/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com