John S
John S

Reputation: 8351

Injecting configuration settings in a Blazor component library?

I have a server-side Blazor web app that I want to be able to add Blazor web component libraries to for "sub apps". I am able to do this by modifying App.Razor and adding AdditionalAssemblies for each component. I have a ServiceCollection extension as part of the component for injecting various services and DbContexts needed by each component. This is then called in the Services section of main app's program.cs file.
So far so good, but now I would like to get the IConfiguration piece somehow passed into the Component so that I can use it throughout the component.

I use the pattern of reading the Appsettings.json file into a set of classes representing the various configuration sections.

Any suggestions on how to do that?

My Component's service extension:

public static class ConfigureServicesExtension
{
    public static void AddMyComponentServices(this IServiceCollection services)
    {
        services.TryAddScoped<MyComponentService>();
        services.AddDbContext<MyDbContext>(options =>
        options.UseSqlServer("name=ConnectionStrings:MyDbContext"));    
    }
}

Upvotes: 1

Views: 2391

Answers (1)

Brian Parker
Brian Parker

Reputation: 14623

In C# ideally your configuration would be a class. Something like:

public class SomeLibraryConfiguration
{
    public string ApplicationTitle { get; set; }
    public string Copyright { get; set; }
}

For this library we want to load it from a particular section "SomeName" from our json file appsettings.json

{
  "ConnectionStrings": {
    "DefaultConnection": "Server=(localdb)\\MSSQLLocalDB;Database=_CHANGE_ME;Trusted_Connection=True;MultipleActiveResultSets=true"
  },
  "SomeName" : {
    "ApplicationTitle" : "My App",
    "Copyright" : "1956 All rights are yours"
  }
}

To load this all you need to do now is create another simple class:

public class LocalConfiguration
{
    public SomeLibraryConfiguration SomeName { get; set; }
}

Then update your extension method. Note the extra parameter. IConfiguration can be passed from builder.Configuration

public static void AddMyComponentServices(this IServiceCollection services, IConfiguration config)
{
    var localConfiguration = config.Get<LocalConfiguration>();

    services.AddScoped(sp => localConfiguration.SomeName);

    services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) });
    services.TryAddScoped<MyComponentService>();
    services.AddDbContext<MyDbContext>(options =>
        options.UseSqlServer("name=ConnectionStrings:MyDbContext"));    
}

In any component:

[Inject]
private SomeLibraryConfiguration Config { get; set; }

Note: IntelliSense works with this approach.

Upvotes: 3

Related Questions