属性的自定义配置活页夹

jce*_*ddy 3 c# asp.net-core asp.net-core-1.1

我在ASP.NET Core 1.1解决方案中使用配置绑定。基本上,我在ConfigureConfigs Startup部分中有一些用于绑定的简单代码,如下所示:

services.AddSingleton(Configuration.GetSection("SettingsSection").Get<SettingsClass>());
Run Code Online (Sandbox Code Playgroud)

麻烦的是,我的类作为int属性,通常绑定到配置文件中的int值,但可以绑定到字符串“ disabled”。在幕后,如果绑定到字符串“ disabled”,我希望该属性的值为-1。

它可能比这更复杂,但是为了简洁起见,我正在简化。

我的问题是:我如何为此提供一个自定义的绑定器/转换器,以覆盖SettingsClass中特定属性的配置绑定,以便在进行字符串转换时将“禁用”转换为-1,而不是抛出“禁用”不能转换为Int32?

Paw*_*rek 6

我最近偶然发现了同样的问题,并提出了略有不同的解决方案。

我的想法是使用默认的绑定机制。就我而言,我想获得在数据库中以正确的数组格式HashSet存储值的新实例。我创建了一个类,将我的配置绑定到一个在我的配置中命名的属性和一个属性,该属性使用该属性为我创建一个. 它看起来有点像这样:privatepublicprivateHashSet

// settings.json
{
    option: {
        ids:[1,2,3],
    }
}
Run Code Online (Sandbox Code Playgroud)

class

public class Options
{
    public HashSet<int> TrueIds
    {
        get
        {
            return RestrictedCategoryIds?.ToHashSet();
        }
    }

    private int[] Ids{ get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后您可以使用BindNonPublicProperties活页夹来确保它会填充您的private财产。

// Startup.cs
services.Configure<Options>(Configuration, c => c.BindNonPublicProperties = true);
Run Code Online (Sandbox Code Playgroud)

你说,在你的情况下,这可能不像将“禁用”转换为-1那么简单,但也许我的想法会启发你以不同的方式解决这个问题。


jce*_*ddy 5

看来,由于ConfigurationBinder使用类型的TypeDescriptor来获取转换器,所以我要做的唯一方法是实现自定义类型转换器,并将其插入要转换为的类的TypeDescriptor中。 (在本例中为Int32)。

因此,基本上,在配置发生之前添加以下代码:

TypeDescriptor.AddAttributes(typeof(int), new TypeConverterAttribute(typeof(MyCustomIntConverter)));
Run Code Online (Sandbox Code Playgroud)

MyCustomIntConverter的外观如下所示:

public class MyCustomIntConverter  : Int32Converter
{
    public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
    {
        if (value != null && value is string)
        {
            string stringValue = value as string;
            if(stringValue == "disabled")
            {
                return -1;
            }
        }
        return base.ConvertFrom(context, culture, value);
    }
}
Run Code Online (Sandbox Code Playgroud)

似乎有些杀伤力,因为对于应用程序中的Int32,现在“禁用”将始终转换为-1。如果有人知道侵入性较小的方法,请告诉我。