Пример #1
0
        /// <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);
        }
Пример #2
0
        /// <summary>
        /// Handles a request for a view model from a browser client.
        /// </summary>
        /// <param name="connectionId">Identifies the client connection.</param>
        /// <param name="vmId">Identifies the view model.</param>
        /// <param name="vmArg">Optional view model's initialization argument.</param>
        public virtual void OnRequestVM(string connectionId, string vmId, object vmArg = null)
        {
            // Create a new view model instance whose class name is matching the given VMId.
            BaseVM vmInstance = !_activeVMs.ContainsKey(vmId) ? CreateVM(vmId, vmArg) : _activeVMs[vmId].Instance;

            RequestVMFilter.Invoke(vmId, vmInstance, vmArg, data =>
            {
                var vmData = Serialize(vmInstance);

                // Send the view model data back to the browser client.
                _vmResponse?.Invoke(connectionId, vmId, vmData);

                // Reset the changed property states.
                vmInstance.AcceptChangedProperties();

                // Add the view model instance to the controller.
                if (!_activeVMs.ContainsKey(vmId))
                {
                    _activeVMs.TryAdd(vmId, new VMInfo {
                        Instance = vmInstance, ConnectionId = connectionId
                    });
                    vmInstance.RequestPushUpdates += VmInstance_RequestPushUpdates;
                }
                else
                {
                    _activeVMs[vmId].ConnectionId = connectionId;
                }

                // If this request causes other view models to change, push those new values back to the client.
                PushUpdates();
            });
        }
Пример #3
0
 public VMInfo(string id, BaseVM instance, string connectionId, string groupName = null)
 {
     Id           = id;
     Instance     = instance;
     ConnectionId = connectionId;
     GroupName    = groupName;
 }
Пример #4
0
        /// <summary>
        /// Runs the view model filter.
        /// </summary>
        /// <param name="hubContext">Hub context.</param>
        /// <param name="vm">View model instance.</param>
        public void RunVMFilters(DotNetifyHubContext hubContext, BaseVM vm, NextFilterDelegate finalFilter)
        {
            var nextFilters = new Stack <NextFilterDelegate>();

            nextFilters.Push(finalFilter);

            // Find and execute the filter that matches each view model class attribute.
            foreach (var attr in vm.GetType().GetTypeInfo().GetCustomAttributes().Reverse())
            {
                var vmFilterType = typeof(IVMFilter <>).MakeGenericType(attr.GetType());
                if (_vmFilterFactories.Keys.Any(t => vmFilterType.IsAssignableFrom(t)))
                {
                    var vmFilter             = _vmFilterFactories.FirstOrDefault(kvp => vmFilterType.IsAssignableFrom(kvp.Key)).Value();
                    var vmFilterInvokeMethod = vmFilterType.GetMethod(nameof(IVMFilter <Attribute> .Invoke));
                    if (vmFilterInvokeMethod != null)
                    {
                        nextFilters.Push(ctx => (Task)vmFilterInvokeMethod.Invoke(vmFilter, new object[] { attr, ctx, nextFilters.Pop() }));
                    }
                }
            }

            var vmContext = new VMContext(hubContext, vm);

            if (nextFilters.Count > 0)
            {
                nextFilters.Pop()(vmContext);
            }
        }
Пример #5
0
        /// <summary>
        /// Adds a runtime reactive property.
        /// </summary>
        /// <param name="vm">View model to add the property to.</param>
        /// <param name="propertyName">Property name.</param>
        /// <param name="propertyValue">Property value.</param>
        /// <returns>Reactive property.</returns>
        public static ReactiveProperty <T> AddReactiveProperty <T>(this BaseVM vm, string propertyName, T propertyValue = default(T))
        {
            var prop = new ReactiveProperty <T>(propertyValue);

            prop.OnChanged(() => vm.Changed(propertyName));
            vm.AddProperty(propertyName, prop);
            return(prop);
        }
Пример #6
0
 /// <summary>
 /// Runs the filter before the view model respond to something.
 /// </summary>
 private void RunRespondingVMFilters(string vmId, BaseVM vm, object vmData, Action <object> vmAction)
 {
     try
     {
         RunVMFilters(nameof(Response_VM), vmId, vm, vmData, vmAction);
     }
     catch (Exception ex)
     {
         _hubPipeline.RunExceptionMiddleware(Context, ex);
     }
 }
Пример #7
0
        /// <summary>
        /// Handles a request for a view model from a browser client.
        /// </summary>
        /// <param name="connectionId">Identifies the client connection.</param>
        /// <param name="vmId">Identifies the view model.</param>
        /// <param name="vmArg">Optional view model's initialization argument.</param>
        /// <returns>Group name, if the request is for a multicast view model associated with one.</returns>
        public async virtual Task <string> OnRequestVMAsync(string connectionId, string vmId, object vmArg = null)
        {
            BaseVM vmInstance = null;

            if (_activeVMs.ContainsKey(vmId))
            {
                vmInstance = _activeVMs[vmId].Instance;
            }
            else
            {
                // Create a new view model instance whose class name is matching the given VMId.
                vmInstance = CreateVM(vmId, vmArg);
                await vmInstance.OnCreatedAsync();
            }

            await RequestVMFilter.Invoke(vmId, vmInstance, vmArg, async data =>
            {
                var vmData = vmInstance.Serialize();

                // Send the view model data back to the browser client.
                await ResponseVMFilter.Invoke(vmId, vmInstance, vmData, filteredData => _vmResponse(connectionId, vmId, (string)filteredData));

                // Reset the changed property states.
                vmInstance.AcceptChangedProperties();

                // Add the view model instance to the controller.
                if (!_activeVMs.ContainsKey(vmId))
                {
                    var vmInfo = new VMInfo(id: vmId, instance: vmInstance, connectionId: connectionId);
                    vmInstance.RequestPushUpdates += VmInstance_RequestPushUpdates;
                    if (vmInstance is MulticastVM)
                    {
                        var multicastVM  = vmInstance as MulticastVM;
                        vmInfo.GroupName = multicastVM.GroupName;
                        multicastVM.RequestMulticastPushUpdates += VMInstance_RequestMulticastPushUpdates;
                        multicastVM.RequestSend += VMInstance_RequestSend;
                    }
                    _activeVMs.TryAdd(vmId, vmInfo);
                }
                else
                {
                    _activeVMs[vmId].ConnectionId = connectionId;
                }

                // If this request causes other view models to change, push those new values back to the client.
                foreach (var vmInfo in _activeVMs.Values)
                {
                    PushUpdates(vmInfo);
                }
            });

            return(_activeVMs[vmId].GroupName);
        }
Пример #8
0
 /// <summary>
 /// Runs the view model filter.
 /// </summary>
 /// <param name="vmId">Identifies the view model.</param>
 /// <param name="vm">View model instance.</param>
 /// <param name="data">View model data.</param>
 /// <param name="vmAction">Filter action.</param>
 private async Task RunVMFilters(BaseVM vm, object data, VMController.VMActionDelegate vmAction)
 {
     try
     {
         _hubContext.Data = data;
         await _hubPipeline.RunVMFiltersAsync(_hubContext, vm, async ctx =>
         {
             await vmAction(ctx.HubContext.Data);
         });
     }
     catch (TargetInvocationException ex)
     {
         throw ex.InnerException;
     }
 }
Пример #9
0
 /// <summary>
 /// Runs the view model filter.
 /// </summary>
 /// <param name="vmId">Identifies the view model.</param>
 /// <param name="vm">View model instance.</param>
 /// <param name="vmArg">Optional view model argument.</param>
 private void RunVMFilters(string callType, string vmId, BaseVM vm, object data, Action <object> vmAction)
 {
     try
     {
         _hubPipeline.RunVMFilters(Context, callType, vmId, vm, data, Principal, ctx =>
         {
             vmAction(ctx.HubContext.Data);
             return(Task.CompletedTask);
         });
     }
     catch (TargetInvocationException ex)
     {
         throw ex.InnerException;
     }
 }
Пример #10
0
 /// <summary>
 /// Runs the view model filter.
 /// </summary>
 /// <param name="vmId">Identifies the view model.</param>
 /// <param name="vm">View model instance.</param>
 /// <param name="data">View model data.</param>
 /// <param name="vmArg">Optional view model argument.</param>
 private void RunVMFilters(BaseVM vm, object data, Action <object> vmAction)
 {
     try
     {
         _hubContext.Data = data;
         _hubPipeline.RunVMFilters(_hubContext, vm, ctx =>
         {
             vmAction(ctx.HubContext.Data);
             return(Task.CompletedTask);
         });
     }
     catch (TargetInvocationException ex)
     {
         throw ex.InnerException;
     }
 }
Пример #11
0
        /// <summary>
        /// Runs the filter before the view model respond to something.
        /// </summary>
        private async Task RunRespondingVMFilters(string vmId, BaseVM vm, object vmData, VMController.VMActionDelegate vmAction)
        {
            try
            {
                _hubContext = new DotNetifyHubContext(_callerContext, nameof(IDotNetifyHubMethod.Response_VM), vmId, vmData, null, Principal);
                await _hubPipeline.RunMiddlewaresAsync(_hubContext, async ctx =>
                {
                    Principal = ctx.Principal;
                    await RunVMFilters(vm, ctx.Data, vmAction);
                });
            }
            catch (Exception ex)
            {
                var finalEx = await _hubPipeline.RunExceptionMiddlewareAsync(_callerContext, ex);

                if (finalEx is OperationCanceledException == false && _callerContext != null)
                {
                    await ResponseVMAsync(_callerContext.ConnectionId, vmId, SerializeException(finalEx));
                }
            }
        }
Пример #12
0
 /// <summary>
 /// Runs the filter before the view model respond to something.
 /// </summary>
 private void RunRespondingVMFilters(string vmId, BaseVM vm, object vmData, Action <object> vmAction)
 {
     try
     {
         _hubContext = new DotNetifyHubContext(Context, nameof(Response_VM), vmId, vmData, null, Principal);
         _hubPipeline.RunMiddlewares(_hubContext, ctx =>
         {
             Principal = ctx.Principal;
             RunVMFilters(vm, ctx.Data, vmAction);
             return(Task.CompletedTask);
         });
     }
     catch (Exception ex)
     {
         var finalEx = _hubPipeline.RunExceptionMiddleware(Context, ex);
         if (finalEx is OperationCanceledException == false)
         {
             Response_VM(Context.ConnectionId, vmId, SerializeException(finalEx));
         }
     }
 }
Пример #13
0
        /// <summary>
        /// Handles a request for a view model from a browser client.
        /// </summary>
        /// <param name="connectionId">Identifies the client connection.</param>
        /// <param name="vmId">Identifies the view model.</param>
        /// <param name="vmArg">Optional view model's initialization argument.</param>
        /// <returns>Group name, if the request is for a multicast view model associated with one.</returns>
        public virtual string OnRequestVM(string connectionId, string vmId, object vmArg = null)
        {
            // Create a new view model instance whose class name is matching the given VMId.
            BaseVM vmInstance = !_activeVMs.ContainsKey(vmId) ? CreateVM(vmId, vmArg) : _activeVMs[vmId].Instance;

            RequestVMFilter.Invoke(vmId, vmInstance, vmArg, data =>
            {
                var vmData = vmInstance.Serialize();

                // Send the view model data back to the browser client.
                _vmResponse?.Invoke(connectionId, vmId, vmData);

                // Reset the changed property states.
                vmInstance.AcceptChangedProperties();

                // Add the view model instance to the controller.
                if (!_activeVMs.ContainsKey(vmId))
                {
                    _activeVMs.TryAdd(vmId, new VMInfo(id: vmId, instance: vmInstance, connectionId: connectionId));
                    vmInstance.RequestPushUpdates += VmInstance_RequestPushUpdates;

                    if (vmInstance is IMulticast)
                    {
                        (vmInstance as IMulticast).RequestMulticastPushUpdates += VMInstance_RequestMulticastPushUpdates;
                    }
                }
                else
                {
                    _activeVMs[vmId].ConnectionId = connectionId;
                }

                // If this request causes other view models to change, push those new values back to the client.
                foreach (var vmInfo in _activeVMs.Values)
                {
                    PushUpdates(vmInfo);
                }
            });

            return(vmInstance is IMulticast ? (vmInstance as IMulticast).GroupName : null);
        }
Пример #14
0
 /// <summary>
 /// Override this method to access instances of subordinates view models before they're disposed.
 /// </summary>
 /// <param name="subVM">Sub-view model instance.</param>
 public virtual void OnSubVMDisposing(BaseVM subVM)
 {
 }
Пример #15
0
 /// <summary>
 /// Override this method to access new instances of subordinates view models as soon as they're created.
 /// </summary>
 /// <param name="subVM">Sub-view model instance.</param>
 public virtual void OnSubVMCreated(BaseVM subVM)
 {
 }
Пример #16
0
        /// <summary>
        /// Returns whether current security context is authorized to access a view model.
        /// </summary>
        /// <param name="vmInstance">View model instance.</param>
        /// <returns>True if authorized.</returns>
        protected virtual bool IsAuthorized(BaseVM vmInstance)
        {
            var authAttr = vmInstance.GetType().GetTypeInfo().GetCustomAttribute <AuthorizeAttribute>();

            return(authAttr == null || authAttr.IsAuthorized(Principal));
        }
Пример #17
0
 /// <summary>
 /// Runs the filter before the view model is updated.
 /// </summary>
 private void RunUpdatingVMFilters(string vmId, BaseVM vm, object vmData, Action <object> vmAction) => RunVMFilters(vm, vmData, vmAction);
Пример #18
0
 /// <summary>
 /// Runs the filter before the view model is requested.
 /// </summary>
 private void RunRequestingVMFilters(string vmId, BaseVM vm, object vmArg, Action <object> vmAction) => RunVMFilters(vm, vmArg, vmAction);
Пример #19
0
 /// <summary>
 /// Updates a value of a view model.
 /// </summary>
 /// <param name="vmInstance">View model instance.</param>
 /// <param name="vmPath">View model property path.</param>
 /// <param name="newValue">New value.</param>
 protected virtual void UpdateVM(BaseVM vmInstance, string vmPath, string newValue)
 {
     vmInstance.DeserializeProperty(vmPath, newValue);
 }
Пример #20
0
 public static void RemoveList <T>(this BaseVM vm, string propName, T itemKey) => vm.ChangedProperties[propName + "_remove"] = itemKey;
Пример #21
0
        /// <summary>
        /// Updates a value of a view model.
        /// </summary>
        /// <param name="vmInstance">View model instance.</param>
        /// <param name="vmPath">View model property path.</param>
        /// <param name="newValue">New value.</param>
        protected virtual void UpdateVM(BaseVM vmInstance, string vmPath, string newValue)
        {
            try
            {
                object vmObject = vmInstance;
                var    vmType   = vmObject.GetType();
                var    path     = vmPath.Split('.');
                for (int i = 0; i < path.Length; i++)
                {
                    var propName = path[i];
                    var propInfo = vmType.GetTypeInfo().GetProperty(propName);
                    if (propInfo == null)
                    {
                        throw new UnresolvedVMUpdateException();
                    }

                    var propType = propInfo.PropertyType.GetTypeInfo();

                    if (i < path.Length - 1)
                    {
                        // Path that starts with $ sign means it is a key to an IEnumerable property.
                        // By convention we expect a method whose name is in this format:
                        // <IEnumerable property name>_get (for example: ListContent_get)
                        // to get the object whose key matches the given value in the path.
                        if (path[i + 1].StartsWith("$"))
                        {
                            var key        = path[i + 1].TrimStart('$');
                            var methodInfo = vmType.GetTypeInfo().GetMethod(propName + "_get");
                            if (methodInfo == null)
                            {
                                throw new UnresolvedVMUpdateException();
                            }

                            vmObject = methodInfo.Invoke(vmObject, new object[] { key });
                            if (vmObject == null)
                            {
                                throw new UnresolvedVMUpdateException();
                            }

                            vmType = vmObject.GetType();
                            i++;
                        }
                        else
                        {
                            vmObject = propInfo.GetValue(vmObject);
                            vmType   = vmObject != null?vmObject.GetType() : propInfo.PropertyType;
                        }
                    }
                    else if (typeof(ICommand).GetTypeInfo().IsAssignableFrom(propInfo.PropertyType) && vmObject != null)
                    {
                        // If the property type is ICommand, execute the command.
                        (propInfo.GetValue(vmObject) as ICommand)?.Execute(newValue);
                    }
                    else if (propType.IsSubclassOf(typeof(MulticastDelegate)) && propType.GetMethod(nameof(Action.Invoke)).ReturnType == typeof(void))
                    {
                        // If the property type is Action, wrap the action in a Command object and execute it.
                        var argTypes = propType.GetGenericArguments();
                        var cmdType  = argTypes.Length > 0 ? typeof(Command <>).MakeGenericType(argTypes) : typeof(Command);
                        (Activator.CreateInstance(cmdType, new object[] { propInfo.GetValue(vmObject) }) as ICommand)?.Execute(newValue);
                    }
                    else if (propInfo.SetMethod != null && vmObject != null)
                    {
                        // Update the new value to the property.
                        if (propType.IsClass && propInfo.PropertyType != typeof(string))
                        {
                            propInfo.SetValue(vmObject, JsonConvert.DeserializeObject(newValue, propInfo.PropertyType));
                        }
                        else
                        {
                            var typeConverter = TypeDescriptor.GetConverter(propInfo.PropertyType);
                            if (typeConverter != null)
                            {
                                propInfo.SetValue(vmObject, typeConverter.ConvertFromString(newValue));
                            }
                        }

                        // Don't include the property we just updated in the ChangedProperties of the view model
                        // unless the value is changed internally, so that we don't send the same value back to the client
                        // during PushUpdates call by this VMController.
                        var changedProperties = vmInstance.ChangedProperties;
                        if (changedProperties.ContainsKey(vmPath) && (changedProperties[vmPath] ?? string.Empty).ToString() == newValue)
                        {
                            object value;
                            changedProperties.TryRemove(vmPath, out value);
                        }
                    }
                }
            }
            catch (UnresolvedVMUpdateException)
            {
                // If we cannot resolve the property path, forward the info to the instance
                // to give it a chance to resolve it.
                vmInstance.OnUnresolvedUpdate(vmPath, newValue);
            }
        }
Пример #22
0
 public static void UpdateList <T>(this BaseVM vm, string propName, T item) => vm.ChangedProperties[propName + "_update"] = item;
Пример #23
0
 /// <summary>
 /// Runs the filter before the view model is requested.
 /// </summary>
 private Task RunRequestingVMFilters(string vmId, BaseVM vm, object vmArg, VMController.VMActionDelegate vmAction) => RunVMFilters(vm, vmArg, vmAction);
Пример #24
0
        /// <summary>
        /// Used in CRUD operations to remove an item from a list.
        /// </summary>
        /// <typeparam name="T">Property type.</typeparam>
        /// <param name="expression">Expression containing property name of the list.</param>
        /// <param name="itemKey">Identifies the list item to be removed.</param>
        public static void RemoveList <T>(this BaseVM vm, Expression <Func <T> > expression, object itemKey)
        {
            var propName = ((MemberExpression)expression.Body).Member.Name;

            vm.RemoveList(propName, itemKey);
        }
Пример #25
0
 public void RunVMFilters(DotNetifyHubContext hubContext, BaseVM vm, NextFilterDelegate finalFilter)
 {
     _ = RunVMFiltersAsync(hubContext, vm, finalFilter);
 }
Пример #26
0
 /// <summary>
 /// Override this method to access instances of subordinates view models before they're disposed.
 /// </summary>
 /// <param name="subVM">Sub-view model instance.</param>
 public virtual void OnSubVMDisposing(BaseVM subVM) => (_vmInstance as IMasterVM)?.OnSubVMDisposing(subVM._vmInstance);
Пример #27
0
        /// <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);
        }
Пример #28
0
 public VMInfo(string id, BaseVM instance, string connectionId)
 {
     Id           = id;
     Instance     = instance;
     ConnectionId = connectionId;
 }
Пример #29
0
 /// <summary>
 /// Runs the filter before the view model is updated.
 /// </summary>
 private Task RunUpdatingVMFilters(string vmId, BaseVM vm, object vmData, VMController.VMActionDelegate vmAction) => RunVMFilters(vm, vmData, vmAction);
Пример #30
0
 /// <summary>
 /// Override this method to access new instances of subordinates view models as soon as they're created.
 /// </summary>
 /// <param name="subVM">Sub-view model instance.</param>
 public virtual void OnSubVMCreated(BaseVM subVM) => (_vmInstance as IMasterVM)?.OnSubVMCreated(subVM._vmInstance);