.NET Core DI调查IConfiguration

德米特里·诺金(Dmitry Nogin)

在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所述,成熟的DI容器(例如Autofac或Simple Injector)将给您带来更多的运气。

如果您真的想继续使用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会导致难以调试堆栈溢出异常。
  • 这个特定的实现是幼稚的,可能会搞砸,因为它会更改注册的顺序。如果您在属于集合的类上使用该属性,或者当您拥有一个可以替换另一种类型的类型(通常通过将注册附加到列表中来工作)时,这可能会中断。要解决此问题,您将必须在列表中与删除旧描述符相同的位置插入新描述符。
  • 可能还会有更多警告,但是这些都是我想起来的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章