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
How to Simulate a Mouse Click at a Certain Position on the Screen
ASP.NET Is There a Better Way to Find Controls That Are Within Other Controls
Difference Between Icomparable and Icomparer
The Difference Between Virtual, Override, New and Sealed Override
Sendinput Doesn't Perform Click Mouse Button Unless I Move Cursor
Total Number of Items Defined in an Enum
What's the Difference Between Utf8/Utf16 and Base64 in Terms of Encoding
Is There a Much Better Way to Create Deep and Shallow Clones in C#
Why Can't C# Use Inline Anonymous Lambdas or Delegates
How to Implement a Singleton in C#
How to Use Acrylic Accent in Windows 10 Creators Update
JSON.Net Adding Backslash While Returning JSON Serialized String
Best Way to Share Data Between Two Child Components in Blazor
Get the Object Is Null Using JSON in Wcf Service
Custom Xmlwriter to Skip a Certain Element
Using Websockets with ASP.NET Web API