简体   繁体   中英

Application Settings in custom class ASP.Net 5 MVC 6

Playing around with ASP.Net 5 MVC. Seen this question jumping around but not an full answer. What I want to do is have a helper class that is able to access the AppSettings. I can access it in the controller and the view but haven't figured out how to access it on my own custom class. Have startup configured like so.

public Startup(IHostingEnvironment env)
    {
        // Set up configuration sources.

        var builder = new ConfigurationBuilder()
            .AddJsonFile("config.json")
            .AddJsonFile($"config.{env.EnvironmentName}.json", optional: true);

        builder.AddEnvironmentVariables();
        Configuration = builder.Build();
    }

    public IConfigurationRoot Configuration { get; set; }

    // This method gets called by the runtime. Use this method to add services to the container.
    // For more information on how to configure your application, visit http://go.microsoft.com/fwlink/?LinkID=398940
    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc();
        services.AddOptions();
        services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
    }
.................
.................

So in your config.json file, suppose you have following settings

{
    "smtp": {
        "SenderEmail": "a@b.com",
        "SenderFrom": "Test User"
    }
}

Then in your ConfigureServices method you need to do something like that

services.Configure<SmtpEmailSetting>(Configuration.GetSection("smtp"));

This is your SmtpEmailSetting looks like

public class SmtpEmailSetting
{
    public string SenderEmail { get; set; }
    public string SenderFrom { get; set; }
}

and this is how you access your settings in any service or controller

public class SendEmailService
{
    private readonly SmtpEmailSetting _smtpEmailSetting;

    public SendEmailService(IOptions<SmtpEmailSetting> smtpOptions )
    {
        _smtpEmailSetting = smtpOptions.Value;
    }

    public void SendEmail()
    {
        var fromEmail = _smtpEmailSetting.SenderEmail;
        var displayName = _smtpEmailSetting.SenderFrom;
    }
}

So basically you use your settings or options (whatever you prefer to call) should be used in constructor as a generic type parameter of IOptions<> class. Hope it helps

In order to access your AppSettings properties in your custom class, make configuration as a static instance such as:

public static IConfigurationRoot Configuration { get; set; }

and make use of your AppSettings any where in your application (for connectionstring example) as:

var connectionString = Startup.Configuration["Data:DefaultConnection:ConnectionString"];

Just to add to adeel41's answer, this is correct and works great, but for myself, I didn't want to drag around an IOption object when using dependency injection.

So I prefer to do something like

services.AddSingleton<ISmtpEmailSettings>(Configuration.GetSection("SmtpSettings").Get<SmtpEmailSettings>());

Most importantly is the Get syntax added to GetSection to deserialize your JSON to an object.

If you need it in your own class, it's probably right to pass it into the constructor of that class, or as a parameter. Eg;

public class Notifications
{
    public Notifications(AppSettings settings) {
        this.settings = settings;
    }

    public void SendEmail(string subject, string body) {
        SmptClient.Send(subject, body, settings["email address"]);
    }
}

So typically, you'd pass it through from your controller.

This avoids a global variable, which is always a good thing, I think.

At the time of RC1, I took inspiration from this post by Rick Strahl, which worked great. That is very similar to other approaches already proposed.

This question is just to update with my findings as of RTM release. It seems like Configuration.GetSection(string topLevelKey) does not work anymore, at least for me it always returns null (even if configuration sources are set correctly).

After some search, this other SO thread pointed me in the right direction, by using:

// create empty config object
var smtpEmailSetting = new SmtpEmailSetting();

// fill it from configuration section
Configuration.GetSection("smtp").Bind(smtpEmailSetting);

// use it, e.g. by registering it into DI
services.Configure<SmtpEmailSetting>(smtpEmailSetting);

HTH

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM