top of page

Options Pattern in C#: How to supply <IOptions>



The IOptions service is used to bind strongly types options class to configuration section and registers it to the Asp.Net Core Dependency Injection Service Container as singleton lifetime. It exposes a Value property which contains your configured TOptions class.


The options pattern is an indirect way to dependency inject settings into a registered service. If you’re using code that implements the options pattern, then you’re required to supply an IOptions<T> object.


For example, let’s say you’re using the MovieService class and it has the following constructor:

public MovieService(IOptions<MovieSettings> options)

This requires you to supply the IOptions<MovieSettings> parameter.

If the settings are in appsettings.json, you can use AddOptions().Bind():

public class Startup
{
	//rest of the class	
	public void ConfigureServices(IServiceCollection services)	
	{
		//rest of method		
		services.AddOptions<MovieSettings>().Bind
						(Configuration.GetSection("MovieSettings"));
	}
}

What if you want to supply hardcoded values, or if you want to fetch the settings from somewhere using a registered service (such as a database repository class)? In this article, I’ll show how to supply the IOptions<T> object in these scenarios.


Supply IOptions<T> with hardcoded values

When you’re using code that implements the options pattern, and you want to use hardcoded values, then you can register the Options<T> object and use Options.Create().


For example, let’s say you want to hardcode the MovieSettings values. Here’s how to supply IOptions<MovieSettings> with hardcoded values:

using Microsoft.Extensions.Options;
public class Startup
{
	//rest of the class	
	public void ConfigureServices(IServiceCollection services)	
	{
		//rest of method		
		services.AddSingleton<IOptions<MovieSettings>>(_ =>
		{
			return Options.Create(new MovieSettings()
			{
				MovieAPIUrl = "https://localhost:12345/movies/api"			
			});
		});
	}
}


Supply IOptions<T> from a registered service

Let’s say you want to supply IOptions<MovieSettings> by fetching MovieSettings from the database using the registered MovieSettingsRepository service.

There are two approaches for doing that:

  • Use AddOptions<MovieSettings>().Configure<IMovieSettingsRepository>().

  • Register IOptions<MovieSettings> directly, allowing you to use Options.Create().

I’ll show both approaches below.


Approach 1 – Use AddOptions<MovieSettings>().Configure<IMovieSettingsRepository>()

With this overload of AddOptions().Configure(), you define a lambda that accepts the MovieSettings object and the resolved IMovieSettingsRepository instance. You can set properties on the MovieSettings object.

public class Startup{
	public void ConfigureServices(IServiceCollection services)	
	{
		services.AddSingleton<IMovieSettingsRepository, 
							MovieSettingsRepository>();
		services.AddOptions<MovieSettings>()
		.Configure<IMovieSettingsRepository>((movieSettings, 
									movieSettingsRepo) =>
		{
			movieSettings.MovieAPIUrl = 
					movieSettingsRepo.GetSettings().MovieAPIUrl;
		});
	}
}

This approach is good if you only want to set a few of the properties.


Approach 2 – Register IOptions<MovieSettings> directly, allowing you to use Options.Create()

You don’t need to use AddOptions(). You can register IOptions<MovieSettings> directly just like anything else. With this approach, you can resolve the IMovieSettingsRepository instance and use it to create the MovieSettings object and pass it to Options.Create().

using Microsoft.Extensions.Options;
public class Startup
{
    //rest of class	
    public void ConfigureServices(IServiceCollection services)	
    {
        //rest of method			
        services.AddSingleton<IMovieSettingsRepository, 
                            MovieSettingsRepository>();
		services.AddSingleton<IOptions<MovieSettings>>(serviceProvider =>
		{
			var repo = serviceProvider.GetService
									<IMovieSettingsRepository>();
			return Options.Create(repo.GetSettings());
		});
	}
}

This approach gives you full control over how the IOptions<MovieSettings> object is supplied.



Resource: makolyte


The Tech Platform

1 comment

1 коментар


Гість
26 бер.

In our pursuit of a solution, we sought assistance from Go Wombat site. Their group wasted little time in getting to the bottom of the issue and fixing it. I'm happy to say that the app is running much better currently, and that there has been a marked increase in interaction. Their knowledge of app development has been a lifesaver for us, and I would gladly suggest them to anyone in a similar situation.

Вподобати
bottom of page