8

To access App Keys in a class library, do we need to do the following code in every class library and class where we need to access a AppKey?

public static IConfigurationRoot Configuration = new ConfigurationBuilder().AddJsonFile("appsettings.json").Build();

This is what I found in Microsoft docs, but this looks very redundant.

Startup class in a project as below

 public class Startup
    {
        public IConfigurationRoot Configuration { get; set; }

        public Startup()
        {
            var builder = new ConfigurationBuilder()
                .AddJsonFile("appsettings.json");

            Configuration = builder.Build();
        }

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddEntityFramework().AddEntityFrameworkSqlServer()
                .AddDbContext<DbContext>(options =>
                    options.UseSqlServer(Configuration["Data:MyDb:ConnectionString"]));
        }
    }

Then how should I inject this "IConfigurationRoot" in each class of a project. And do I have to repeat this Startup class in each class Library? Why is this not part of .NET Core Framework?

1
  • 1
    Dude! someone must be really crazy to down-vote question with out even being qualified to have an account in SO, Who ever down voted this question, if you don't know .NET, find a tutor to teach you .NET in 30 days, just don't irritate me. And that DB don't even have quality of commenting why he/she is doing this BS act. This is very Annoying. SO team should really do some thing about these kind of acts Commented Jul 26, 2016 at 18:08

2 Answers 2

10

The recommended way is to use the options pattern, provided by Microsoft and used heavily in ASP.NET Core.

Basically you create a strong typed class and configure it in the Startup.cs class.

public class MySettings 
{
    public string Value1 { get; set; }
    public string Value2 { get; set; }
}

and initialize it in the Startup class.

// load it directly from the appsettings.json "mysettings" section
services.Configure<MySettings>(Configuration.GetSection("mysettings"));

// do it manually
services.Configure<MySettings>(new MySettings 
{
    Value1 = "Some Value",
    Value2 = Configuration["somevalue:from:appsettings"]
});

then inject these options everywhere you need it.

public class MyService : IMyService
{
    private readonly MySettings settings;

    public MyService(IOptions<MySettings> mysettings) 
    {
        this.settings = mySettings.Value;
    }
}
Sign up to request clarification or add additional context in comments.

13 Comments

That's nothing but repeating this code in every class i need to access mySettings? isn't that a redundant work?
No, you only have one single Startup.cs class: In your web application and nowhere else! In class libraries and all other services you only inject IOptions<MySettings> mysettings into the class. And no it's not redundant, because you only read/instantiate it once and pass it around everywhere (you let the new built-in Dependency Injection Container do the work). Class libraries should never have a Startup.cs
Is this the only way .NET Core works? By injecting IOptions in each class where I need to access a Setting?
That's one of the reasons (ASP).NET Core ships with a built-in DI container and the IOptions<T> pattern was introduced. It is used in every of the ASP.NET Core libraries to pass configuration, just hidden behind the extensions methods like services.AddMvc( options => ...) github.com/aspnet/Mvc/blob/1.0.0/src/…. You don't have to use it, but it's easier and works well with the idea of dependency injection. Fighting against it just may make stuff harder/more complicated
See stackoverflow.com/questions/41150178/ioptions-injection/… Of course nothing prevents you from injecting typed classes (T) rather than IOptions<T> into your services, but then you will need to register the typed classes yourself (in a separate class which references Microsoft.Extensions.DependecyInjection.Abstractions, but you loose certain aspects of the options pattern, like updating the options value when someone edits the appsettings.json. With options pattern, this is supported out of the box
|
4

By the principle of Information Hiding in Object-Oriented Programming, most classes should not need to have access to your application configuration. Only your main application class should need to directly have access to this information. Your class libraries should expose properties and methods to alter their behavior based on whatever criteria their callers deem necessary, and your application should use its configuration to set the right properties.

For example, a DateBox shouldn't need to know how timezone information is stored in your application configuration file - all it needs to know is that it has a DateBox.TimeZone property that it can check at runtime to see what timezone it is in.

5 Comments

If I get you correctly, are you saying I should not try to access AppKeys from any class Libraries rather I should pass values as Params from my Main Project (like Web site)?
Yes, that is correct. When you encounter something like that that makes you feel like your code is awkward, step back and consider how the creators of the functionality you are using might have envisioned its use. It is very easy, especially when you are relatively new to OOP, to want to shortcut good design patterns and expose your data anywhere and everywhere. It can come back and hurt you later when you find out that your dependencies are so tight that changing anything has become a nightmare.
One way that this can help is if you want to create more generic class libraries that will work with Web Forms applications, MVC applications, Windows Forms applications, and/or console applications. Most libraries shouldn't care where they are, and shouldn't have to deal with the fact that configuration information may be stored in different places for different kinds of apps.
The possible way to avoid dependency of IOptions is to use extension TConfig ConfigurePOCO<TConfig>(this IServiceCollection services, IConfiguration configuration), as suggested in strathweb.com/2016/09/…
It's maybe semantics but the access to the configuration is still maintained by the application. The only thing that is communicated via the options are it's values how and when to use them is up to the object.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.