Home > Blockchain >  How can I use different modules based on application settings?
How can I use different modules based on application settings?

Time:05-17

I am new in asp.net core and I would like to set the property value during start up in asp.net core web API. The data is fetched from Data base and I need the values through out the application and it should be called only once.

There is two states in my project lets assume it to be A and B. In A there is one set of items are shown and in the B there are different items shown. I get a application setting data from the Database and on the basis of that data i will either show the A module or the B module through out the application life.

CodePudding user response:

A general solution to this problem would be to configure a singleton object to be registered in the ServiceCollection.

services.AddSingleton<ISingletonObject, SingletonObject>();

The constructor for such an object would load the necessary data, and then use constructor injection to load the singleton object into each class (e.g. controller).

public class SomeController(ISingletonObject singletonObject)
{
     // singleton object will be injected with it's pre-loaded data available   
}

The constructor for object SingletonObject will only be executed once, regardless of how many other constructors it is injected into by the service collection.

CodePudding user response:

There are no global variables in .NET, much less C#. Storing configuration data in global, static properties is a bad idea because it ties your code with the static class that holds those properties, making it harder to write or test code.

Configuration Middleware

ASP.NET Core solves this through the Configuration middleware which can read configuration settings from multiple providers, including files, databases and even in-memory collections. The Configuration overview article shows how to use a dictionary as a configuration source :

var builder = WebApplication.CreateBuilder(args);

var Dict = new Dictionary<string, string>
        {
           {"MyKey", "Dictionary MyKey Value"},
           {"Position:Title", "Dictionary_Title"},
           {"Position:Name", "Dictionary_Name" },
           {"Logging:LogLevel:Default", "Warning"}
        };

builder.Host.ConfigureAppConfiguration((hostingContext, config) =>
{
    config.Sources.Clear();

    config.AddInMemoryCollection(Dict);

    config.AddEnvironmentVariables();

    if (args != null)
    {
        config.AddCommandLine(args);
    }
});

builder.Services.AddRazorPages();

var app = builder.Build();

After that, all classes can retrieve the configuration values, no matter where they come from, through the IConfiguration interface :

public class TestModel : PageModel
{
    // requires using Microsoft.Extensions.Configuration;
    private readonly IConfiguration Configuration;

    public TestModel(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public ContentResult OnGet()
    {
        var myKeyValue = Configuration["MyKey"];
        var title = Configuration["Position:Title"];
        var name = Configuration["Position:Name"];
        var defaultLogLevel = Configuration["Logging:LogLevel:Default"];


        return Content($"MyKey value: {myKeyValue} \n"  
                       $"Title: {title} \n"  
                       $"Name: {name} \n"  
                       $"Default Log Level: {defaultLogLevel}");
    }
}

In your case you could load the settings from a database and register them as an in-memory source in your Program.cs :

var Dict=LoadDataAsDictionary();
...
    config.AddInMemoryCollection(Dict);
...

Dependency Injection Middleware

Another option is to load the data as a strongly typed object and register it as a Signleton instance using the Dependency Injection middleware :

var builder = WebApplication.CreateBuilder(args);

MyCacheData cacheData=LoadStronglyTypedData();

builder.Services.AddSingleton(cachedata);

This class can be injected into pages and controllers just like other DI services or IConfiguration :

public class TestModel : PageModel
{

    private readonly MyCacheData Data;

    public TestModel(MyCacheData data)
    {
        Data = data;
    }
  • Related