I've got this bit of code for a factory method to produce singletons. I have a small MAUI app and want to have persistent global data.
public static class FactoryService
{
private static BudgetViewModel budgetViewModelInstance;
private static AccountsViewModel accountsViewModelInstance;
private static PayeesViewModel payeesViewModelInstance;
public static BaseViewModel BuildViewModel(Type type)
{
if(type == typeof(BudgetViewModel))
{
budgetViewModelInstance ??= new BudgetViewModel();
return budgetViewModelInstance;
}
else if(type == typeof(AccountsViewModel))
{
accountsViewModelInstance ??= new AccountsViewModel();
return accountsViewModelInstance;
}
else if(type == typeof(PayeesViewModel))
{
payeesViewModelInstance ??= new PayeesViewModel();
return payeesViewModelInstance;
}
else
{
throw new Exception($"Can't build View Model. Invalid View Model: {type}");
}
}
}
Then when I want a view model reference, I have to cast the type I want before calling BuildViewModel:
BudgetViewModel budgetViewModel = (BudgetViewModel)FactoryService.BuildViewModel(typeof(BudgetViewModel));
Is this.... right? Is there a better way to accomplish this? I can't use static classes for the view models because they have to inherit from ObservableObject. (from the Community MVVM Toolkit)
CodePudding user response:
I would use generics. Something like this:
public static class FactoryService
{
private static BudgetViewModel budgetViewModelInstance;
private static AccountsViewModel accountsViewModelInstance;
private static PayeesViewModel payeesViewModelInstance;
private static readonly object _lock = new object();
public static T BuildViewModel<T>() where T : BaseViewModel, new()
{
if (typeof(T) == typeof(BudgetViewModel))
{
if (budgetViewModelInstance == null)
{
lock (_lock)
{
if (budgetViewModelInstance == null)
{
budgetViewModelInstance = new();
}
}
}
return budgetViewModelInstance as T;
}
else if (typeof(T) == typeof(AccountsViewModel))
{
if (accountsViewModelInstance == null)
{
lock (_lock)
{
if (accountsViewModelInstance == null)
{
accountsViewModelInstance = new();
}
}
}
return accountsViewModelInstance as T;
}
else if (typeof(T) == typeof(PayeesViewModel))
{
if (payeesViewModelInstance == null)
{
lock (_lock)
{
if (payeesViewModelInstance == null)
{
payeesViewModelInstance = new();
}
}
}
return payeesViewModelInstance as T;
}
else
{
throw new Exception($"Can't build View Model. Invalid View Model: {typeof(T)}");
}
}
}
Then you can invoke like this:
var viewModel = FactoryService.BuildViewModel<BudgetViewModel>();