/// <summary> /// Creates a view model. /// </summary> /// <param name="vmId">Identifies the view model.</param> /// <param name="vmArg">Optional view model's initialization argument.</param> /// <param name="vmNamespace">Optional view model type's namespace.</param> /// <returns>View model instance.</returns> protected virtual BaseVM CreateVM(string vmId, object vmArg = null, string vmNamespace = null) { // If the namespace argument is given, try to resolve the view model type to that namespace. vmNamespace = vmNamespace ?? ExtractNamespace(ref vmArg); // If the view model Id is in the form of a delimited path, it has a master view model. BaseVM masterVM = null; var path = vmId.Split('.'); if (path.Length > 1) { // Get the master view model; create the instance if it doesn't exist. var masterVMId = vmId.Remove(vmId.LastIndexOf('.')); lock (_activeVMs) { if (!_activeVMs.ContainsKey(masterVMId)) { masterVM = CreateVM(masterVMId, null, vmNamespace); _activeVMs.TryAdd(masterVMId, new VMInfo { Instance = masterVM }); } else { masterVM = _activeVMs[masterVMId].Instance; } } vmId = vmId.Remove(0, vmId.LastIndexOf('.') + 1); } // If the view model Id contains instance Id, parse it out. string vmTypeName = vmId; string vmInstanceId = null; if (vmTypeName.Contains('$')) { path = vmTypeName.Split('$'); vmTypeName = path[0]; vmInstanceId = path[1]; } // Get the view model instance from the master view model, and if not, create it ourselves here. var vmInstance = masterVM?.GetSubVM(vmTypeName, vmInstanceId) ?? _vmFactory.GetInstance(vmTypeName, vmInstanceId, vmNamespace) ?? throw new Exception($"[dotNetify] ERROR: '{vmId}' is not a known view model! Its assembly must be registered through VMController.RegisterAssembly."); // If there are view model arguments, set them into the instance. if (vmArg is JObject) { foreach (var prop in (vmArg as JObject).Properties()) { UpdateVM(vmInstance, prop.Name, prop.Value.ToString()); } } // Pass the view model instance to the master view model. masterVM?.OnSubVMCreated(vmInstance); return(vmInstance); }
/// <summary> /// Creates a view model. /// </summary> /// <param name="vmId">Identifies the view model.</param> /// <param name="vmArg">Optional view model's initialization argument.</param> /// <param name="vmNamespace">Optional view model type's namespace.</param> /// <returns>View model instance.</returns> protected virtual BaseVM CreateVM(string vmId, object vmArg = null, string vmNamespace = null) { // If the namespace argument is given, try to resolve the view model type to that namespace. vmNamespace = vmNamespace ?? ExtractNamespace(ref vmArg); // If the view model Id is in the form of a delimited path, it has a master view model. BaseVM masterVM = null; var path = vmId.Split('.'); if (path.Length > 1) { // Get the master view model; create the instance if it doesn't exist. var masterVMId = vmId.Remove(vmId.LastIndexOf('.')); lock (_activeVMs) { if (!_activeVMs.ContainsKey(masterVMId)) { masterVM = CreateVM(masterVMId, null, vmNamespace); _activeVMs.TryAdd(masterVMId, new VMInfo { Instance = masterVM }); } else { masterVM = _activeVMs[masterVMId].Instance; } } vmId = vmId.Remove(0, vmId.LastIndexOf('.') + 1); } // If the view model Id contains instance Id, parse it out. string vmTypeName = vmId; string vmInstanceId = null; if (vmTypeName.Contains('$')) { path = vmTypeName.Split('$'); vmTypeName = path[0]; vmInstanceId = path[1]; } // Get the view model instance from the master view model. var vmInstance = masterVM?.GetSubVM(vmTypeName, vmInstanceId); // If still no view model instance, create it ourselves here. if (vmInstance == null) { Type vmType = null; if (vmNamespace != null) { vmType = _vmTypes.FirstOrDefault(i => i.FullName == $"{vmNamespace}.{vmTypeName}"); } vmType = vmType ?? _vmTypes.FirstOrDefault(i => i.Name == vmTypeName); if (vmType == null) { throw new Exception($"[dotNetify] ERROR: '{vmId}' is not a known view model! Its assembly must be registered through VMController.RegisterAssembly."); } try { if (vmInstanceId != null) { vmInstance = CreateInstance(vmType, new object[] { vmInstanceId }) as BaseVM; } } catch (MissingMethodException) { Trace.Fail($"[dotNetify] ERROR: '{vmTypeName}' has no constructor accepting instance ID."); } try { if (vmInstance == null) { vmInstance = CreateInstance(vmType, null) as BaseVM; } } catch (MissingMethodException) { Trace.Fail($"[dotNetify] ERROR: '{vmTypeName}' has no parameterless constructor."); } } // If there are view model arguments, set them into the instance. if (vmArg is JObject) { foreach (var prop in (vmArg as JObject).Properties()) { UpdateVM(vmInstance, prop.Name, prop.Value.ToString()); } } // Pass the view model instance to the master view model. masterVM?.OnSubVMCreated(vmInstance); return(vmInstance); }