Как объявить модель глобальных переменных в BLAZOR WASM? Допустим, у меня есть следующая модель, и я хочу иметь доступ к каждой переменной из модели в любом месте всего моего проекта (страницы, службы, компоненты, где угодно). Не могли бы вы мне помочь ?
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";
}
Вы можете внедрить свой класс как одноэлементный сервис:
builder.Services.AddSingleton<UserInfoGlobalClass>();
Включите в услугу класс как ctor
параметр.
В компоненте или на странице:
@inject UserInfoGlobalClass UserInfoGlobalClass
Хотя бы для того, чтобы это было динамично. Вам нужно будет украсить свой класс событием, чтобы уведомлять страницы и компоненты о вызове StateHasChanged()
при обновлении содержимого. Обычно я устанавливаю свойства в частный набор и предоставляю метод для их изменения, который, наконец, вызывает событие для уведомления слушателей.
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();
}
}
Используйте в другом сервисе.
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;
}
На странице или компоненте:
@implements IDisposable
@inject UserInfoGlobalClass UserInfoGlobalClass
...
@code {
protected override void OnInitialized()
{
userInfoGlobalClass.UserChangedEvent += StateHasChanged;
}
public void public void Dispose() => userInfoGlobalClass.UserChangedEvent -= StateHasChanged;
}
На самом деле я сделал это на основе этого видео youtube.com/watch?v=u5Y8s1hgEOU . Но я не могу использовать модель глобальных переменных из другого сервиса, потому что получаю сообщение об ошибке. Скажите, пожалуйста, как я могу использовать UserInfoGlobalClass внутри другой службы, потому что я хочу использовать одну или несколько переменных из другой службы. @inject UserInfoGlobalClass UserInfoGlobalClass в другом сервисе не работает. Можете ли вы предоставить более подробную информацию для: «Вам нужно будет украсить свой класс событием, чтобы уведомлять страницы и компоненты о вызове StateHasChanged() при обновлении содержимого». ? Спасибо
@TomCat Я дополнил свой ответ, надеюсь, это поможет.
Суть такова: я хочу иметь доступ ко всем глобальным переменным из общедоступного класса UserInfoGlobalClass во всем проекте! Все глобальные переменные из общедоступного класса UserInfoGlobalClass инициализируются до требуемых значений только тогда, когда пользователь входит в систему и выходит из нее. Можете ли вы предоставить мне самый простой способ сделать то, что я хочу? Большое спасибо !
Как насчет использования CascadingParameter? Быстрый пример:
В MainLayout.razor — в разделе @code:
private UserInfoGlobalClass userInfo = new UserInfoGlobalClass();
В MainLayout.razor — вокруг раздела @Body:
<CascadingValue Value = "@userInfo">
@Body
</CascadingValue>
Затем в любом из ваших компонентов, где вам нужно получить доступ к объекту UserInfoGlobalClass — в разделе @code:
[CascadingParameter]
public UserInfoGlobalClass? userInfo { get; set; }
В моем случае я бы просто передал объект или требуемую переменную в качестве параметра службам, где мне нужно ее использовать:
MyComponent.razor:
{
await MyService.Get(userInfo);
}
MyService.cs:
public List<MyObject> Get(UserInfoGlobalClass userInfo)
{
//...service logic here
}
В моем собственном проекте я использую это, например, когда мне нужно передать CurrentUser (ApplicationUser) нескольким компонентам во всем моем проекте, и я хочу загрузить текущего пользователя только один раз. Вы можете узнать больше об использовании каскадных параметров здесь.
Однако при использовании каскадных параметров может иметь недостатки и компромиссы. Что мне нравится в каскадных параметрах, так это то, что при изменении каскадного значения новое значение будет отправлено вниз по дереву компонентов, и все компоненты, которые его используют, будут обновлены. Но это может иметь проблемы с производительностью, если значения постоянно меняются.
Проголосовали за, так как это хорошее решение для обработки текущей информации о пользователе, которая меняется не очень часто. У этого также есть некоторые преимущества: Microsoft — каскадные значения и параметры Blazor
Внедрить модель как услугу.