0

I'm trying to allow the constructor to accept IConfiguration for .Net, and a reference to ConfigurationManager or similar for .Net Framework/Standard.


I am trying to create a conditional constructor for a class that needs to know which runtime it's running against - namely whether it's in a Framework, or .NET solution.

The solution that this class resides in is written against .Net Standard, but will be consumed by .Net Framework 4.8, .Net Standard 2.0 and .Net 6/7 applications/packages.

Initially I thought conditional compilation would be the answer, with this as an example:

#if NETSTANDARD || NETFRAMEWORK
    //do stuff
#elif NET
    //do different stuff
#endif

However, this is not about compilation time - it will always be compiled to .Net Standard.

Is there a way to figure out what runtime is being used, and conditionally present constructors that way?

I could just include all constructors and include comments on what to use when, but i feel like that will be ignored, and if i could force the correct usage, it would be simpler.

I'm trying to allow the constructor to accept IConfiguration for .Net, and a reference to ConfigurationManager or similar for .Net Framework/Standard.

Worse - i'm trying to do this without different compilations as this is the only real area where the package i'm updating differs in functionality between .Net and Framework.

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
user3012708
  • 793
  • 1
  • 11
  • 33
  • 3
    What are you trying to do? There are no .NET Standard applications, that's purely a library target. As you said, this isn't about compilation time so you can't use conditional compilation or different constructors. You can create a package that targets multiple runtimes, but why do you need to do that *in the constructor* ? – Panagiotis Kanavos Jun 09 '23 at 08:24
  • Sorry! To be more clear - iI was lumping .Net Standard & Framework apps together as they can both use ConfigurationManager. This package can also be consumed by other packages that are written against .Net Standard. Though eventually, consumed by a .Net or a Framework app. As for what - i'm trying to vary the injection of configuration variables into the constructor. In one place i will pass IConfiguration in, in another I will pass a reference to ConfigurationManager. Since ConfigurationManager won't work on .Net, i want to ensure that constructor cannot be used, etc. – user3012708 Jun 09 '23 at 09:18
  • I've updated my post to reflect my comment above. It's easy to miss key detail when you have the problem wrapped up in your head, and don't communicate it well. – user3012708 Jun 09 '23 at 09:22
  • `Microsoft.Extensions.Configuration` is a .NET Standard 2 library and *can* be used in .NET Framework. There's a `Sysctem.Configuration.ConfigurationManager` compatibility package meant to ease migration from .NET Framework to .NET Core. You don't have to use different constructors – Panagiotis Kanavos Jun 09 '23 at 09:30
  • Do you really need to use `app.config` in .NET Framework? Or can use use `Microsoft.Extensions.Configuration` as well? If you can, you can use `Microsoft.Extensions.Configuration.Abstractions` in your package instead of dual-targeting – Panagiotis Kanavos Jun 09 '23 at 09:34
  • In this [probably related question](https://stackoverflow.com/questions/45034007/using-app-config-in-net-core) the [latest answer](https://stackoverflow.com/a/75189199/134204) reads settings using ConfigurationManager and stores them in a `MemoryConfigurationSource` that's used with IConfiguration. Sure, it's a bit "dirty" but solves the problem with just a few lines – Panagiotis Kanavos Jun 09 '23 at 09:40
  • Thanks for the suggestions. I currently have references to the Microsoft.Extensions.Configuration and Microsoft.Extensions.Configuration.Json, and end up reading the appsettings.json file manually using those, as the ConfigurationManager package doesn't support .json files. I absolutely need to use app.config, unfortunately (hundreds of projects already with this in use that cannot be updated just yet). So - we're back to how it began, and i can't simply hide one constructor if it's not applicable (right?). I guess in this case, i would hide the "ConfigurationManager" one from .Net apps. – user3012708 Jun 09 '23 at 09:42
  • 1
    Did you check the linked answer? You can load the settings from `app.config` into a `MemoryConfigurationSource`. This isn't about constructors at all, it's about handling both kinds of configuration. You assumed you needed different constructors for this, but that's not true. Since everything is moving to `IConfiguration`, that's the only thing you really depend on. You also need a way to load `app.config` – Panagiotis Kanavos Jun 09 '23 at 10:09
  • Oh, that's a good point! I've been thinking from the opposite direction! (i.e. trying to add appsettings.json support rather than trying to add app.config support) I will give it a go later today. Thanks! – user3012708 Jun 09 '23 at 10:12
  • In fact, you could solve the problem by creating a `WithAppConfig` extension method that uses ConfigurationManager to read the settings and register them with ConfigurationBuilder. Or, you could create a `FromAppConfig` that creates the Config builder, calls `WithAppConfig` and uses that in your application. The .NET Framework applications would only have to call one or the other – Panagiotis Kanavos Jun 09 '23 at 10:13
  • You could put those extension methods in a *separate* library/package too, to avoid taking a dependency on ConfigurationManager in your main library – Panagiotis Kanavos Jun 09 '23 at 10:15
  • I resolved it in the same way it was resolved in the post you linked in the end. Thankyou very much for the discussion with let my thinking evolve to other ways of seeing the problem! If you put that up as an answer, i will accept it. – user3012708 Jun 13 '23 at 12:17

0 Answers0