using System; using System.Diagnostics; using Avalonia.Controls; using CommunityToolkit.Mvvm.ComponentModel; using CommunityToolkit.Mvvm.Messaging; using Nitrox.Launcher.Models; namespace Nitrox.Launcher.ViewModels.Abstract; public abstract class ViewModelBase : ObservableValidator, IMessageReceiver { protected Window MainWindow => AppViewLocator.MainWindow; protected ViewModelBase() { ThrowIfViewModelCtorWasEmptyWhileNonEmptyExists(); } public virtual void Dispose() => WeakReferenceMessenger.Default.UnregisterAll(this); /// /// This will check that DI did not call the empty ViewModel constructor if dependencies for another constructor aren't met. /// [Conditional("DEBUG")] private static void ThrowIfViewModelCtorWasEmptyWhileNonEmptyExists() { if (Design.IsDesignMode) { return; } foreach (StackFrame stackFrame in new StackTrace(2, false).GetFrames()) { if (stackFrame.GetMethod() is not { IsConstructor: true } method) { continue; } if (method.DeclaringType is not { IsAbstract: false } declaringType) { continue; } if (method.GetParameters().Length > 0 || declaringType.GetConstructors().Length == 1) { break; } throw new Exception($"Empty ViewModel constructor of '{declaringType.Name}' should only be used in design mode! Check that the DI-container has all the dependencies to call a different constructor."); } } }