13

I am migrating the .netframework 4.7.2 class library to .netstandard 2.0 library.

ConfigurationManager is used in the .netframework class library to read the app settings.

Any alternative option available for the System.Configuration.ConfigurationManager in .netstanard.

The migrated class library needs to be used in a .net core web API and old .netframework web application.

Manu
  • 168
  • 1
  • 1
  • 8
  • 4
    If you're doing a library, try to avoid accessing the configuration file at all. Instead, your library classes should expect to have the configuration that they need passed into them by the hosting application. That keeps your library flexible and doesn't tie you down to any specific implementation. It might take a bit of refactoring, but shouldn't be too terrible. – mason Apr 30 '20 at 17:31
  • @mason Do you have any example or link to the example? – Manu May 01 '20 at 07:47
  • you can also bind your configuraiton to a POCO class and pass that around instead so you don't have a configuration dependency everywhere – sommmen May 01 '20 at 08:55

3 Answers3

7

You could install ConfigurationManager via nuget package, which targets .Net Standard 2.0.

As for ASP.Net Core, have a look at Microsoft.Extensions.Configuration.

weichch
  • 9,306
  • 1
  • 13
  • 25
5

As I said, you should not depend directly on how the configuration is obtained in a class library. Keep your class library flexible.

Don't do this in your class library:

public void UpdateProductName(int productId, string name)
{
    using (var connection = new SqlConnection(ConfigurationManager.ConnectionStrings["MyDatabase"]))
    {
        connection.ExecuteNonQuery("UPDATE dbo.Products SET Name = @Name WHERE Id = @ProductId", new {  ProductId = productId, Name = name });
    }
}

By directly using ConfigurationManager in your class library, you've tied the class to only allowing one form of obtaining the connection string. That means if you want to use appsettings.json, or environment variables, or KeyVault, or any other method of obtaining configuration, you can't.

Instead, do this:

public class MyDatabaseRepository
{
    readonly string _connectionString;

    public MyDatabaseRepository(string connectionString)
    {
        _connectionString = connectionString;
    }
} 

public void UpdateProductName(int productId, string name)
{
    using (var connection = new SqlConnection(_connectionString))
    {
        connection.ExecuteNonQuery("UPDATE dbo.Products SET Name = @Name WHERE Id = @ProductId", new {  ProductId = productId, Name = name });
    }
}

Now that allows you to obtain a connection string however you want in the consuming application.

In a .NET Core app, you might do this to get the connection string from appsettings.json via Microsoft.Extensions.Configuration:

string connectionString = Configuration.GetConnectionString("MyDatabase");
MyDatabaseRepository repository = new MyDatabaseRepository(connectionString);
repository.UpdateProductName(1, "Transformer");

And it still allows you the flexibility to use System.Configuration in your .NET Framework app:

string connectionString = ConfigurationManager.ConnectionStrings["MyDatabase"].ConnectionString;
MyDatabaseRepository repository = new MyDatabaseRepository(connectionString);
repository.UpdateProductName(1, "Transformer");

Coupled with Dependency Injection, this becomes a very flexible and powerful tool.

mason
  • 31,774
  • 10
  • 77
  • 121
2

Thanks to this answer: https://stackoverflow.com/a/54259119/672110

If you check the result of the call to ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);

I added a ProjName.dll.config to a .Net 5 Web project, and that allowed a NetStandard2.0 project to get config values from ConfigurationManager.ConnectionStrings["x"] and ConfigurationManager.AppSettings["y"]

While this is clearly the wrong way to develop new code, this is allowing us to move forward with a large .Net Framework migration to .Net 6.

StormRider01
  • 335
  • 5
  • 19