Pedro Horta
Pedro Horta

Reputation: 9

How can I retrieve data from a Scoped Service in a Singleton Service?

We've been facing an issue in our Blazor Server App

  1. User Logs in.
  2. When user is Authenticated is shown a companies list.
  3. User can choose between one of the companies in the list.
  4. In this moment we need to save the CompanyDBName and CompanyUi of the choosen company (The only place we found to store this was ProtectedSessionStorage [Scoped Service], because it's a place with a life cicle of the session, beggining in the user login and ending in user logout).
  5. We have MainService (MUST be Singleton Service, because it contains other application relevant data) with a DbConnectionString property that stores the connection string without any Initial Catalog and a method GetCompanyConnectionString() that adds CompanyDbName to DbConnectionString and returns CompanyDbConnetionString.
  6. CompanyDbConnection string is used in all Factories that works with DataBase.

The Issue:

public class MainService
{
    private readonly ProtectedSessionStorage _protectedSessionStorage;

    public string DbConnectionString{ get; set; } = "Data Source=localhost\SQLEXPRESS;Initial Catalog=;Integrated Security=True";

    public SessionDataService(ProtectedSessionStorage protectedSessionStorage)
    { 
        // ***The Error Happens Here *** - in the Injection of ProtectedSessionStorage
        _protectedSessionStorage = protectedSessionStorage; 
    }
    
    async Task<string> GetCompanyConnectionString()
    {
        // Get CompanyDbName from ProtectedSessionStorage
        var companyDbName = await _protectedSessionStorage.GetAsync<string>("UserDb");
        
        // Add to CompanyDbName to DbConnectionString (that is common to all sessions) 
        SqlConnectionStringBuilder builder = new SqlConnectionStringBuilder(DbConnectionString);
        builder.InitialCatalog = companyDbName;
        
        // returns ConnectionString that we use by A session in the DataBaseFactory calls 
        return builder.ToString();
    }
}

builder.Services.AddSingleton<MainService>();

Upvotes: 0

Views: 61

Answers (1)

Qiang Fu
Qiang Fu

Reputation: 8811

MainService (MUST be Singleton Service, because it contains other application relevant data)

From my understanding, you need it to be singleton because it stores/initiates some data even when user is not login. Then you could use it as scoped and store/retrive data from protected LocalStorage.

If it must be singleton anyway, then GetCompanyConnectionString hasn't to be a method in MainService. You could create another scope service for it.

Upvotes: 0

Related Questions