在 Simple Injector 中生成 Func<TParam1, TParam2, TService> 工厂

Generate Func<TParam1, TParam2, TService> factories in Simple Injector

我在容器中注册了一些服务。还有一些依赖于此服务的类型 and 短暂的争论。例如:

public class Foo
{
    public Foo(IService1 svc1, IService2 svc2, int entityId) { }
}

我想要的是某种方法来自动生成用于创建此类对象的工厂,而无需手动对每个工厂进行编码。我可以使用 Func<int, Foo> 或创建一些 IFooFactory (使用 CreateFoo(int entityId) 方法)并且我想让简单注入器自动生成这个工厂的实现(以某种通用的方式用于任何数量的参数) .

可能吗?

查看 SimpleInjector github 页面中的 AutomaticParameterizedFactoryExtensionsTests class。它有一个测试方法,解释了如何使用 AutomaticParameterizedFactoryExtensions,这似乎是你所要求的。

这个class在源代码的SimpleInjector.CodeSamples项目中。

DI 库用于创建长期服务的对象图。您正试图滥用您的容器来构建一个短暂的 class。实体、消息和 DTO 等短期对象通常称为 newables,因为您应该手动新建它们,而不是让您的组合根或容器为您自动连接它们。

如果此 Foo 是一个实体,则依赖项 should not be injected into the entity's constructor。应该改用方法注入;一个实体有多个域方法,这些方法应该指定它们需要的依赖关系。调用该域方法的组件可以将这些依赖项注入到其构造函数中。在运行时,您可以将这些依赖项传递给实体的方法。

将运行时数据与编译时依赖项混合到 classes 的构造函数中有很多缺点。例如,它使您的对象图难以验证,这当然适用于注入 Func<TParam1, TParam2, Entity>。以 class 为例,它接受两个相同类型的参数,例如 public Bar(IService1, int a, int b) 将相应的 Func<int, int, Bar> 方法注入到消费者中。但是,如果 Bar 更改为 public Bar(IService1, int b, int a)(交换 ab 会怎么样)?在那种情况下,代码将在运行时失败;编译器和我们的 DI 库都无法为我们检测到这一点。