简单注入器:使用构造函数参数注册开放泛型类型

Simple Injector: Registering open generic type with constructor parameter

我创建了一个泛型

public interface IContext<T> {}

而且,我实现了一个类型(使用带参数的构造函数)

public class Context<T> : IContext<T> { public Context(string url, string key) { } ... }

我想注册简单的注射器。使用下面的代码,我不知道如何为构造函数传递值

container.Register(typeof(IContext<>), typeof(Context<>))

This 如果我在构造函数参数中传递了一个类型,则显示了一种方法。但是,对我来说它只是原始类型。看起来通过覆盖构造解析行为我可以实现这一点。但是,我真的不知道我该如何利用它。有人可以指导我找到合适的注册方式吗?

在将原始依赖关系处理到开放通用注册中时,典型的解决方案是将配置值集提取到 DTO 中,并将该 DTO 注入到类型的构造函数中;这允许您将该新配置对象作为单例注册到容器中:

我创建了一个泛型

public 接口 IContext {}

而且,我实现了一个类型(使用带参数的构造函数)

public class ContextConfiguration
{
    public readonly string Url;
    public readonly string Key;
    public ContextConfiguration(string url, string key) { ... }
}

public class Context<T> : IContext<T>
{
    public Context(ContextConfiguration config)
    {
    }
    ...
}

// Configuration
container.RegisterSingleton(new ContextConfiguration(...));
container.Register(typeof(IContext<>), typeof(Context<>));

如果您无法更改该类型的构造函数,您可以创建一个该类型的子 class,并将其放置在 Composition Root 中。此子类型再次使用此配置 DTO:

// Part of the Composition Root
private class ContextConfiguration
{
    public readonly string Url;
    public readonly string Key;
    public ContextConfiguration(string url, string key) { ... }
}

private class CompositionRootContext<T> : Context<T>
{
    public Context(ContextConfiguration config) : base(config.Url, config.Key)
    {
    }
    ...
}

// Configuration
container.RegisterSingleton(new ContextConfiguration(...));
container.Register(typeof(IContext<>), typeof(CompositionRootContext<>));

如果 Context<T> 是密封的,您可以重写 parameter injection behavior, but in general, in that case you are dealing with a type that is defined by an external library. For external types it is generally better to hide them behind an application-tailored abstraction (according to the DIP). Instead of letting application code depend on IContext<T>, you let the application depend on an interface that is defined by the application. As part of your Composition Root, you would implement an Adapter,使应用程序特定的接口适应 Context<T>。该适配器的构造函数将再次能够使用此配置 DTO。