Puis-je utiliser des enregistrements C # 9 comme IOptions?
Je viens de commencer à jouer avec C # 9 et .NET 5.0, en particulier la nouvelle record
construction. Je trouve que j'ai beaucoup d'excellents cas d'utilisation pour la syntaxe abrégée des types d'enregistrement.
L'un des cas d'utilisation que j'ai envisagés était d'utiliser un record
pour le dto dans IOptions<>
, au lieu de classes régulières, pour les applications ASP.NET Core. Ces classes d'options sont généralement assez simples, donc j'ai pensé que ce serait un ajustement parfait, mais il semble que je ne puisse pas le faire fonctionner facilement, car la configuration de l'application à l'aide de IOptions<>
l'objet nécessite un constructeur sans paramètre.
public record MyOptions(string OptionA, int OptionB);
public class Startup
{
public void ConfigureServices(IServiceCollection services) {
services.Configure<MyOptions>(Configuration.GetSection(nameof(MyOptions)));
}
...
}
public class MyController : Controller
{
private readonly MyOptions _options;
public MyController(IOptions<MyOptions> options) {
_options = options.Value; // This throws an exception at runtime
}
}
L'exemple ci-dessus lève l'exception suivante lors de la tentative d'accès à la IOption<>.Value
propriété:
System.MissingMethodException: 'Aucun constructeur sans paramètre défini pour le type' AcmeSolution.MyOptions '.'
Existe-t-il un moyen de configurer le IOptions
système de configuration pour désérialiser les options à l'aide du constructeur de l'enregistrement au lieu de nécessiter un constructeur sans paramètre?
Je pourrais utiliser la syntaxe à long terme pour les enregistrements, mais il n'y a vraiment aucun avantage à utiliser une classe.
Réponses
Existe-t-il un moyen de configurer le système de configuration IOptions pour désérialiser les options à l'aide du constructeur de l'enregistrement au lieu de nécessiter un constructeur sans paramètre?
Non, en général, ASP.Net Core utilise beaucoup d'instanciation de type au moment de l'exécution, ce qui nécessite des appels de constructeur connus à l'avance, et dans ce cas, il nécessite un constructeur sans arguments.
Vous pouvez cependant faire en sorte que votre classe d'enregistrement ait un constructeur sans paramètre:
public record MyOptions(string OptionA, int OptionB)
{
public MyOptions(): this(default, default) {}
}
Est-ce que ça vaut le coup? Eh. À toi de voir. Ce n'est pas pire qu'un cours régulier, en termes de performances, alors allez-y avec ce que vous trouvez plus clair!
Edit: vous devriez également pouvoir utiliser ce formulaire:
public record MyOptions(string OptionA = default, int OptionB = default);