1

So I've been following this guide, but all examples are either accessing the options in the same method in which they were declared or in a controller. For the life of me, I can't figure out how to get it to work with any random class.

Here's my current code:

appsettings.json

{
  "Settings": {
    "GameServerVersion": 14
  },
  ....
}

Settings.cs

public class Settings
{
    public int GameServerVersion { get; set; }
}

Startup.cs

public Startup(IHostingEnvironment env)
{
    var builder = new ConfigurationBuilder()
        .SetBasePath(env.ContentRootPath)
        .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
        .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true)
        .AddEnvironmentVariables();
    this.Configuration = builder.Build();
}

public IConfigurationRoot Configuration { get; }

// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
    // Add framework services.
    services.AddMvc();
    services.AddCors();
    services.AddOptions();

    services.Configure<Settings>(this.Configuration.GetSection("Settings"));

    JobManager.StartAsync();
}

JobManager.cs

public class JobManager
{
    private static IScheduler scheduler;

    public static async void StartAsync()
    {
        // Quartz.NET jobs
        // Setup scheduler, register jobs, etc.
        // Trying to retrieve ```Settings.GameServerVersion``` to pass it to one of the jobs
    }
}

Now the guide suggests I should be using the following (applied to my example):

private readonly Settings settings;

public JobManager(IOptions<Settings> settingsAccessor)
{
    settings = settingsAccessor.Value;
}

And this is where I start to get lost. I understand I could just use the following, but I don't know what or how to pass the relevant parameter to the constructor.

JobManager jm = new JobManager(); // cannot use an empty constructor obviously
jm.StartAsync(); // no longer a static method

Any help or guidance would be much appreciated, as I'm still very new to C#.

2
  • You should register your JobManager in dependency injection container (services.AddSingleton or similar) and resolve it from there instead of manually constructing. Commented Aug 16, 2017 at 13:32
  • Could you maybe go into a bit more detail? I think I understand what you mean, but am rather unsure about the implementation Commented Aug 16, 2017 at 13:39

1 Answer 1

3

It's better to not perform any static initialization (like static RunAsync in your case) when you use dependency injection container. Instead, register JobManager itself (preferrably through interface) in container (assuming you pass IOptions though constructor as in your example):

services.AddSingleton<JobManager>();

Then, later, for example in Configure method in your Startup class, resolve it and start:

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) {
    var jm = app.ApplicationServices.GetService<JobManager>();
    jm.StartAsync();
    // etc
}

If you will need to use JobManager in any controller - just pass it though constructor - it will be resolved automatically.

Sign up to request clarification or add additional context in comments.

2 Comments

Sir, you are a true hero, thank you very much. The GetService part was the missing link. Is it possible to get this to work with IOptionsSnapshot as well?
@ChrisSatchell IOptionsSnapshot is no different. You register some stuff in dependency injection container (or in case of IOptions or IOptionsSnapshot - framework does that) and you can pass that as arguments to constructor of any other stuff registered in the same container.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.