-2

I'm trying to use Microsoft's "hosting/logging/configuration/dependency injection" thing for a new console app in .Net 5.0. A little background first: I'm totally new to all that, and I have never used any of the similar stuff that's apparently long been available in ASP.NET (in fact I don't think I've ever even used ASP.NET at all, and if I did, it was long long ago, and in a very small way). With that said:

I feel like I'm missing something regarding configuration, specifically with binding a section of appsettings.json (or whatever) to an options class. Let's say I have a preexisting class -- not specifically intended for use with Microsoft's DI/etc. framework -- that takes some sort of options class in its constructor:

public X(XOptions options) {
   this.Blah = options.OneThirtySeventhBlah * 37;
}

I found various examples of how to get stuff from appsettings.json into my code:

services.Configure<XOptions>(options => hostContext.Configuration.GetSection("X").Bind(options));

But upon running with that, I found (to my surprise) that it wouldn't work with my preexisting X class. To get it to work, I also had to change X's constructor (or, I guess, at least add a new constructor) to take an IOptions<XOptions> instead of simply taking an XOptions:

public X(IOptions<XOptions> options) {
   this.Blah = options.Value.OneThirtySeventhBlah * 37;
}

That works fine and all, but... am I missing something here? Do I really have to change my pre-existing class (which, again, is not specifically for use in this type of framework) to have all this additional Microsoft stuff as a dependency?

I suppose I could instead write a MicrosoftifiedX class, taking an IOptions<XOptions> in its constructor and implementing the same interface as X does, and make that part of an optional package, but... like I said, I feel like I'm missing something. Can I really not just bind the configuration directly to XOptions? If I can, how?

And if I can't, then I can't help but imagine that there might be some standard (or at least reasonably widespread) framework/pattern/library for dealing with this that's less tedious than my MicrosoftifiedX idea. Does anyone know of such a thing? Thanks.

Bob Vesterman
  • 1,127
  • 1
  • 11
  • 31
  • No, you don't "need to". Do whatever makes sense for your application. `IOptions`, `IOptionsMonitor` and `IOptionsSnapshot` can be extremely useful, if you need the functionality. If you just need a static value, I don't see the problem with injecting a singleton of the options. However, this is all completely opinionated. – Camilo Terevinto Oct 31 '21 at 09:42
  • Yes, thanks, "Do I need to" was poor phrasing for a place like this, and was intended to rhetorically express surprise, not as a "real" question in and of itself. If the people downvoting and voting to close for "more than one question" and "opinion-based" could please just forgive me and pretend that I only asked my question of how to bind directly from config to `XOptions` so as to use the existing implementation of `X` without modification, that would be terrific. Thanks. – Bob Vesterman Oct 31 '21 at 09:48
  • If you can remove all the unnecessary text (which reads like ranting) and leave just the essence of your question (how to get data from appsettings.json without using `IOptions`), I'd be glad to remove the downvote, but notice though that there are duplicates available, like https://stackoverflow.com/questions/43679665/read-and-use-settings-from-appsettings-json-without-ioptionst – Camilo Terevinto Oct 31 '21 at 10:11

1 Answers1

1

Yes you can and, in my opinion you should, prevent from letting your line-of-business classes take a dependency on IOption<T>. Instead, register the options object as singleton:

XOptions xoptions = config.GetSection("SectionName").Get<XOptions>();

// Verify XOptions here (if required)

// Register XOptions as singleton
services.AddSingleton<XOptions>(xoptions);
services.AddTransient<IX, X>(); // X takes a dependency on XOptions
Steven
  • 166,672
  • 24
  • 332
  • 435
  • Thank you so much! Just a little note: I'm not sure if this is because I'm misunderstanding your answer, missing something necessary prior to it, or if it's just a little mistake in your example: When I try to `GetSection("Root:SectionName")`, the `IConfigurationSection` that is returned does not exist (according to its `Exists()` method). But if I change it to `GetSection("SectionName")` instead, it works great. Thanks again! – Bob Vesterman Oct 31 '21 at 23:09