简体   繁体   English

Simple Injector:使用构造函数参数注册开放通用类型

[英]Simple Injector: Registering open generic type with constructor parameter

I have created a generic type 我创建了一个通用类型

public interface IContext<T> {}

And, I have a type implemented that (with a constructor with parameters) 而且,我实现了一个类型(使用带有参数的构造函数)

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

I want to register with simple injector. 我想向简单的注射器注册。 With the below code, I dont know how to pass the values for the constructor 使用下面的代码,我不知道如何传递构造函数的值

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

This one shows a way if I have a type passed in the constructor parameter. 如果我在构造函数参数中传递了一种类型,则此图显示了一种方法。 However, for me its primitive types only. 但是,对我来说,它只是原始类型。 Looks like by overriding construction resolution behaviour I may achieve this. 通过覆盖构造分辨率行为,我可以实现这一目标。 But, dont really get the idea of how shall I leverage it. 但是,请不要真正了解如何利用它。 Can someone guide me to find an appropriate way to register this? 有人可以指导我找到合适的方式进行注册吗?

When dealing with primitive dependencies into an open-generic registration, the typical solution is to extract the set of configuration value(s) into a DTO and inject that DTO into the type's constructor; 在将原始依赖项处理为开放通用注册时,典型的解决方案是将一组配置值提取到DTO中,然后将该DTO注入到类型的构造函数中。 this allows you to register that new configuration object as singleton into the container: 这使您可以将新配置对象作为单例注册到容器中:

I have created a generic type 我创建了一个通用类型

public interface IContext {} 公共接口IContext {}

And, I have a type implemented that (with a constructor with parameters) 而且,我实现了一个类型(使用带有参数的构造函数)

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<>));

In case you can't change the constructor of that type, you create a sub class of that type that you place inside the Composition Root . 如果您无法更改该类型的构造函数,请创建一个放置在Composition Root内的该类型的子类。 This sub type again uses this configuration DTO: 此子类型再次使用此配置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<>));

If that Context<T> is sealed, you could override the parameter injection behavior , but in general, in that case you are dealing with a type that is defined by an external library. 如果Context<T>是密封的,则可以覆盖参数注入行为 ,但是通常,在这种情况下,您要处理的是由外部库定义的类型。 For external types it is generally better to hide them behind an application-tailored abstraction (according to the DIP ). 对于外部类型,通常最好将它们隐藏在针对应用程序定制的抽象后面(根据DIP )。 Instead of letting application code depend on IContext<T> , you let the application depend on an interface that is defined by the application. 不用让应用程序代码依赖于IContext<T> ,而是让应用程序依赖于应用程序定义的接口。 As part of your Composition Root, you would implement an Adapter that adapts the application-specific interface to Context<T> . 作为“合成根”的一部分,您将实现一个Adapter ,该适配器将特定于应用程序的接口适应Context<T> The constructor of that adapter would -again- be able to use this configuration DTO. 该适配器的构造函数将再次能够使用此配置DTO。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM