Using Iconfiguration in C# Class Library

Using IConfiguration in C# Class Library

Never used it but a quick search lead me to this...

var configuration = new Configuration();
configuration.AddJsonFile("config.json");
var emailAddress = configuration.Get("emailAddress");

Maybe you could try that.

Access from class library to appsetting.json in Asp.net-core

I'm assuming you want to access the appsettings.json file from the web application since class libraries don't have an appsettings.json by default.

I create a model class that has properties that match the settings in a section in appsettings.json.

Section in appsettings.json

"ApplicationSettings": {
"SmtpHost": "mydomain.smtp.com",
"EmailRecipients": "me@mydomain.com;other@mydomain.com"
}

Matching model class

namespace MyApp.Models
{
public class AppSettingsModel
{
public string SmtpHost { get; set; }
public string EmailRecipients { get; set; }
}
}

Then populate that model class and add it to the IOptions collection in the DI container (this is done in the Configure() method of the Startup class).

services.Configure<AppSettingsModel>(Configuration.GetSection("ApplicationSettings"));

// Other configuration stuff

services.AddOptions();

Then you can access that class from any method that the framework calls by adding it as a parameter in the constructor. The framework handles finding and providing the class to the constructor.

public class MyController: Controller
{
private IOptions<AppSettingsModel> settings;

public MyController(IOptions<AppSettingsModel> settings)
{
this.settings = settings;
}
}

Then when a method in a class library needs the settings, I either pass the settings individually or pass the entire object.

Cannot access appsettings.json from class library

You're very close, but you need to fix a few things. SqlDataAccess implements IConfigManager. Why? What's that providing? Instead, you should have it implement an interface that allows it to expose the functionality other classes depend on.

public interface ISqlDataAccess
{
List<T> LoadData<T>(string sql);

int SaveData<T>(string sql, T data);
}

Change your SqlDataAccess class to implement this interface...

public class SqlDataAccess : ISqlDataAccess

And of course, wire this up with your DI container.

services.AddTransient<ISqlDataAccess, SqlDataAccess>();

Now, any class that needs to run SQL can take a dependency on the ISqlDataAccess interface, utilizing constructor injection to get an instance of ISqlDataAccess. Since we've told the DI container to provide a SqlDataAccess instance when the ISqlDataAccess dependency is present, it will all wire up nicely in your app.

Then we have the issue with ShortUrlProcessor. You declared that class as static. That's bad, because it makes it difficult for it to use constructor injection to get its dependencies, and any other class that needs to invoke its methods has to do so directly, rather than via an abstraction. That violates the Dependency Inversion Principle of SOLID. And since we should always strive to write SOLID code because of the maintainability and testability, we need to fix that.

public class ShortUrlProcessor : IShortUrlProcessor
{
readonly ISqlDataAccess _dataAccess;

public ShortUrlProcessor(ISqlDataAccess dataAccess)
{
_dataAccess = dataAccess;
}

public ShortURLModel GetOriginalURL(string shortUrl)
{
string sql = $@"SELECT * FROM dbo.shorturl WHERE shortUrl = '{ shortUrl }'";
var originalURLEnum = _dataAccess.LoadData<ShortURLModel>(sql); //<--- problem
return originalURLEnum.First();
}
}

And we'll need an interface so other classes don't have to depend directly on ShortUrlProcessor...

public interface IShortUrlProcessor
{
ShortURLModel GetOriginalURL(string shortUrl);
}

And of course, we need to register it with our DI container.

services.AddTransient<IShortUrlProcessor, ShortUrlProcessor>();

Then any class that needs to access the functionality of ShortUrlProcessor can do so via the abstraction IShortUrlProcessor. You mentioned you have a controller calling this, so let's wire that up too.

public class MyController()
{
readonly IShortUrlProcessor _shortUrlProcessor;

public MyController(IShortUrlProcessor shortUrlProcessor)
{
_shortUrlProcessor = shortUrlProcessor;
}

public ActionResult SomeActionMethod()
{
var model = _shortUrlProcessor.GetOriginalURL("asdf");
return View(model);
}
}

We don't have to create an interface for the controller, because the controller will be called by the framework. And we don't have to wire up the controller with the DI container, because the framework handles that for us.

By doing all this, we can easily test individual methods in isolation. There's still some improvements to be made (the SQL Injection attack I mentioned in the comments needs to be fixed), but it's a good step in the right direction.

How to supply configuration from Web API to class library dependency

If the 'TestUtility' class is registered in the DI container, you can inject the configuration into that class's constructor.

    public class TestUtility
{
private readonly string _homeAddress;

public TestUtility(IConfiguration configuration)
{
_homeAddress = configuration["HomeAddress"]
}

public string ConfigTest()
{
return _homeAddress;
}
}

How do I access Configuration in any class in ASP.NET Core?

Update

Using ASP.NET Core 2.0 will automatically add the IConfiguration instance of your application in the dependency injection container. This also works in conjunction with ConfigureAppConfiguration on the WebHostBuilder.

For example:

public static void Main(string[] args)
{
var host = WebHost.CreateDefaultBuilder(args)
.ConfigureAppConfiguration(builder =>
{
builder.AddIniFile("foo.ini");
})
.UseStartup<Startup>()
.Build();

host.Run();
}

It's just as easy as adding the IConfiguration instance to the service collection as a singleton object in ConfigureServices:

public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<IConfiguration>(Configuration);

// ...
}

Where Configuration is the instance in your Startup class.

This allows you to inject IConfiguration in any controller or service:

public class HomeController
{
public HomeController(IConfiguration configuration)
{
// Use IConfiguration instance
}
}


Related Topics



Leave a reply



Submit