How Can I Declare A Global Variables Model In BLAZOR WASM? Let's say I have the following model and I want to be able to access every variable from the model anywhere in my entire project (pages, services, components, anywhere). Can you help me, please ?
public class UserInfoGlobalClass
{
public string User_Name { get; set; } = "JOHN SMITH";
public string User_Email { get; set; } = "[email protected]";
public string User_Role { get; set; } = "Administrator";
public string USER_ID { get; set; } = "85f04683-0d37-4947-a09d-bbb464a92480";
}
CodePudding user response:
How about using a CascadingParameter? Quick example:
To make your variables available across all components:
In MainLayout.razor - in the @code section:
private UserInfoGlobalClass userInfo = new UserInfoGlobalClass();
In MainLayout.razor - Around the @Body section:
<CascadingValue Value="@userInfo">
@Body
</CascadingValue>
Then, in any of your components where you need to access the UserInfoGlobalClass object - in the @code section:
[CascadingParameter]
public UserInfoGlobalClass? userInfo { get; set; }
To use these variables in a service:
In my case, I would simply pass the object or required variable as a parameter to the services where I need to use it:
MyComponent.razor:
{
await MyService.Get(userInfo);
}
MyService.cs:
public List<MyObject> Get(UserInfoGlobalClass userInfo)
{
//...service logic here
}
In my own project, I use this, for example, when I need to pass the CurrentUser (ApplicationUser) to several components across my entire project, and want to load the current user only once. You can read more about using cascading parameters here.
However, using Cascading Parameters could have drawback and trade-offs. What I like about Cascading Parameters, is that if a cascading value is changed then the new value will be sent down the component tree and all components that use it will be updated. But this can have performance issues if the values constantly change.
CodePudding user response:
You can inject your class as a singleton service:
builder.Services.AddSingleton<UserInfoGlobalClass>();
In a service include the class as a ctor
paramater.
In a component or page:
@inject UserInfoGlobalClass UserInfoGlobalClass
For this to be dynamic though. You will need to embellish your class with an event to notify pages and components to call StateHasChanged()
when the contents are updated. I normally set the properties to private set and expose a method to change them that finally invokes the event to notify listeners.
public class UserInfoGlobalClass
{
public string User_Name { get; private set; } = "JOHN SMITH";
public string User_Email { get; set; } = "[email protected]";
public string User_Role { get; set; } = "Administrator";
public string USER_ID { get; set; } = "85f04683-0d37-4947-a09d-bbb464a92480";
public event EventHandler UserChangedEvent;
public void SetUser(User user)
{
User_Name = user.Name;
... repeat for properties.
UserChangedEvent?.Invoke();
}
}
Use in another service.
builder.Services.AddScoped<SomeOtherService>();
public class SomeOtherService : IDisposable
{
private readonly UserInfoGlobalClass userInfoGlobalClass;
public SomeOtherService(UserInfoGlobalClass userInfoGlobalClass)
{
this.userInfoGlobalClass = userInfoGlobalClass;
userInfoGlobalClass.UserChangedEvent = UserChanged;
}
public void UserChanged(object sender, EventArgs e)
{
// Process user details change.
}
public void SetNewUserMethod()
{
userInfoGlobalClass.SetUser(new User { ... });
}
public void Dispose() => userInfoGlobalClass.UserChangedEvent -= UserChanged;
}
In a page or component:
@implements IDisposable
@inject UserInfoGlobalClass UserInfoGlobalClass
...
@code {
protected override void OnInitialized()
{
userInfoGlobalClass.UserChangedEvent = StateHasChanged;
}
public void public void Dispose() => userInfoGlobalClass.UserChangedEvent -= StateHasChanged;
}