繁体   English   中英

.NET Core DI 查看 IConfiguration

[英].NET Core DI looking into IConfiguration

在 ASP.NET Core DI 中支持基于属性的设置参考解析的最简单方法是什么? 我想做这样的事情来读取配置值:

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
    public WeatherForecastController(
        [Setting("Logging:LogLevel:Microsoft")] string logLevel)
    {
        …

appsettings.json看起来像:

{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft": "Warning",
      …

任何想法如何处理它? 我希望它也适用于服务。

从技术上讲,使用 MS.DI 可以实现这一点,但这样做非常困难,而且正如 Dmitry 所提到的,使用 Autofac 或 Simple Injector 等成熟的 DI 容器会更幸运。

如果您真的想继续使用 MS.DI,这里有一些代码可以帮助您入门:

var settingDescriptors = (
    from descriptor in services
    let type = descriptor.ImplementationType
    where type != null && !type.IsGenericTypeDefinition
    where type.GetConstructors().Single().GetParameters()
        .Any(p => p.GetCustomAttribute<SettingAttribute>() != null)
    select descriptor)
    .ToArray();

foreach (var descriptor in settingDescriptors)
{
    services.Remove(descriptor);

    object[] settings = // TODO: Determine settings from parameters here

    services.Add(new ServiceDescriptor(
        descriptor.ServiceType,
        c => ActivatorUtilities.CreateInstance(
            c,
            descriptor.ImplementationType,
            settings),
        descriptor.Lifetime));
}

这段代码的作用是遍历服务集合并替换所有注册的实现,该实现具有用SettingAttribute标记的构造函数参数。 该注册被替换为使用工厂委托的注册,该委托要求 DI 容器创建一个实例,同时为其提供一个或多个对象(设置)。 换句话说,它在手动提供对象时启用自动连线。

这意味着,在某种程度上,这对于 MS.DI 来说是可能的,但是......您应该考虑一些严重的限制:

  • 此代码不适用于开放通用注册。 事实上,这是 MS.DI 的一个限制,它阻止您有效地将此方法应用于开放泛型类型。
  • 一旦应用,您就不能应用以相同方式工作的其他扩展,因为一旦将实现类型的描述符替换为使用工厂委托的描述符,DI 系统就会变得盲目。 例如,如果您使用 Scrutor(在 MS.DI 之上工作)应用装饰器,您可能会看到一些奇怪的行为,具体取决于应用它们的顺序。
  • ActivatorUtilities.CreateInstance的使用使 DI 系统失明。 在 MS.DI 包含防止循环依赖的检查的情况下,使用ActivatorUtilities.CreateInstance将导致在循环依赖的情况下难以调试堆栈溢出异常。
  • 这个特定的实现是幼稚的,并且可能会搞砸,因为它改变了注册的顺序。 如果您在作为集合的一部分的类上使用该属性,或者当您有一个替换另一种类型的类型(通常通过将注册附加到列表来工作)时,这可能会中断。 要解决此问题,您必须将新描述符插入列表中与删除旧描述符的位置相同的位置。
  • 可能还有更多警告,但这些是我能从脑海中回忆起来的。

暂无
暂无

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

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