0

I have a .NET Standard 2.0 assembly that I have been using with my MVC and Webforms applications to do some Entity Framework stuff. In all the applications I have simply used:

ConfigurationManager.ConnectionStrings[""]

however .NET Core does not support this and instead insists that I use Configuration.

So I have two questions:

  1. Is there a built in platform agnostic (does not matter if it is Webforms, MVC, .NET Core) way I can use in .NET Standard to read connection strings?
  2. From within a .NET Standard assembly how do I determine if I am being called from .NET Core vs Anything else so that I can use either Configuration or ConfigurationManager? I am guessing I am going to have to liberally sprinkle target framework conditionals everywhere?
TheEdge
  • 9,291
  • 15
  • 67
  • 135
  • See this https://stackoverflow.com/questions/47591910/is-configurationmanager-appsettings-available-in-net-core-2-0 – Dmitriy Sep 15 '19 at 23:36
  • @Dmitriy That post talks about pulling in the old configuration manager. While doable that seems like a code smell. Is there really no .Net Standard solution to this? – TheEdge Sep 16 '19 at 01:31
  • "196 Yes, ConfigurationManager.AppSettings is available in .NET Core 2.0 after referencing NuGet package System.Configuration.ConfigurationManager. Credits goes to @JeroenMostert for giving me the solution." Is it enough for you? – Dmitriy Sep 16 '19 at 01:34
  • My code is in a .Net STANDARD library, that is accessed from both .Net Core and MVC, Webforms. So adding ConfigurationManager is not the issue here. It is an AGNOSTIC way to do it when BOTH .Net Core and MVC/Webforms access the STANDARD library. – TheEdge Sep 16 '19 at 01:37
  • The agnostic way is simple: do not do this, and insist your clients explicitly pass the connection strings to the classes that need them (i.e. use dependency injection). This is the route .NET Core has chosen as opposed to passing globals around, and is the approach compatible with both. It's not correct to assume an application will use any one particular way, regardless of platform. Ported .NET Core apps may choose to stick with `ConfigurationManager` to reduce the amount of code that has to be changed, or then again they might not -- you can't reliably detect this at runtime. – Jeroen Mostert Sep 16 '19 at 12:24
  • For "ease of use", you could consider using `ConfigurationManager` if and only if clients choose not to pass in the connection strings themselves (i.e. offer overloads), so .NET Framework clients and those ported to .NET Core would "naturally" use `ConfigurationManager`. But then again this might confuse or inconvenience "pure" .NET Core applications, and you may wish to offer different versions instead (possibly with conditionals, as you've specified). There is no one correct solution to that; it depends on what kind of clients you intend to serve. – Jeroen Mostert Sep 16 '19 at 12:27

1 Answers1

0

This seems to be use case of Dependency Injection. Using ConfigurationManager.* or Environment.* in a class library is anyway not a good practice. Consider these settings as dependencies for the library and inject environment/framework/application specific settings from caller of the library.

// Class is part of this or common library
public class AppSettings
{
    public string AppDbConnectionString { get; set; }

    // more settings
}

public class MyLib
{
    private srting _connectionString;

    // Inject settings 
    public MyLib(AppSettings settings)
    {
        _connectionString = settings.AppDbConnectionString;    
    }
}
Sarvesh Gupta
  • 85
  • 3
  • 9
  • While I understand the dependency injection argument it is slightly overkill. Previously I was able to manipulate a configuration file as part of CI and it all just worked. As this code is used by both my WebForms/MVC and now .NET Core code I was hoping to use the same config approach because ultimately they have configuration files anyway. I will now have to retrofit all my Webforms/MVC apps to pass data around because of .NET Core. – TheEdge Sep 17 '19 at 11:13
  • @TheEdge: if you want .NET Core but with standard configuration files, you still can -- you can simply reference `System.Configuration.ConfigurationManager` and away you go. If you're going to allow configuration "the .NET Core way", you cannot assume they will even use configuration files in the first place, as .NET Core configuration is much more flexible, but you are not *required* to do so. The `System.Configuration.ConfigurationManager` package is a .NET Standard package and is thus available to Core. You can use a pay-as-you-go approach for porting; behavior is not mandated. – Jeroen Mostert Sep 17 '19 at 14:55