using System; using System.Collections.Generic; using NodeNetwork.ViewModels; using NodeNetwork.Views; using ReactiveUI; using Splat; namespace NodeNetwork { /// /// A locator is used to find the correct view corresponding to a viewmodel. /// In ReactiveUI, usually Splat is used, but others exist. This class acts as an intermediate registrar. /// It gathers registrations and registers them to the preferred locator. /// public sealed class NNViewRegistrar { private static readonly List, Type>> PendingRegistrations = new List, Type>>(); private static Action, Type> _registerAction; public static void AddRegistration(Func factory, Type serviceType) { if (factory == null) { throw new ArgumentNullException(nameof(factory)); } else if (serviceType == null) { throw new ArgumentNullException(nameof(serviceType)); } if (_registerAction == null) { PendingRegistrations.Add(Tuple.Create(factory, serviceType)); } else { _registerAction(factory, serviceType); } } public static void RegisterToLocator(Action, Type> newRegisterAction) { if (newRegisterAction == null) { throw new ArgumentNullException(nameof(newRegisterAction)); } else if (_registerAction != null) { throw new InvalidOperationException("A locator has already been set"); } _registerAction = newRegisterAction; foreach (var t in PendingRegistrations) { _registerAction(t.Item1, t.Item2); } PendingRegistrations.Clear(); } /// /// Register all NodeNetwork view/viewmodel pairs to Locator.CurrentMutable. /// public static void RegisterSplat() { RegisterToLocator((f, t) => Locator.CurrentMutable.Register(f, t)); } } }