public static AuthorizationRules.AuthorizeOperation ToAuthorizationOperation(this PortalOperation operation) { switch (operation) { case PortalOperation.Create: case PortalOperation.CreateChild: return(AuthorizationRules.AuthorizeOperation.Create); case PortalOperation.Fetch: case PortalOperation.FetchChild: return(AuthorizationRules.AuthorizeOperation.Fetch); case PortalOperation.Insert: case PortalOperation.InsertChild: case PortalOperation.Update: case PortalOperation.UpdateChild: return(AuthorizationRules.AuthorizeOperation.Update); case PortalOperation.Delete: case PortalOperation.DeleteChild: return(AuthorizationRules.AuthorizeOperation.Delete); default: break; } throw new Exception($"{operation.ToString()} cannot be converted to AuthorizationOperation"); }
public MethodInfo MethodForOperation(PortalOperation operation, IEnumerable <Type> criteriaTypes) { var methods = MethodsForOperation(operation); MethodInfo matchingMethod = null; if (methods != null) { foreach (var m in methods) { var parameters = m.GetParameters(); // No criteria if (!criteriaTypes.Any() && !parameters.Any()) { return(m); } else if (criteriaTypes.Any() && parameters.Any() && parameters.Count() >= criteriaTypes.Count()) { var match = true; var critEnum = criteriaTypes.GetEnumerator(); var paramEnum = parameters.Cast <ParameterInfo>().Select(p => p.ParameterType).GetEnumerator(); // With Array's Current doesn't become null var paramHasValue = paramEnum.MoveNext(); var critHasValue = critEnum.MoveNext(); // All of the criteria parameter types match up // And any left over are registered while (match && paramHasValue) { if (critHasValue && !paramEnum.Current.IsAssignableFrom(critEnum.Current)) { match = false; } else if (!critHasValue && !Scope.IsRegistered(paramEnum.Current)) // For recognizing multiple positives for the same criteria { match = false; } paramHasValue = paramEnum.MoveNext(); critHasValue = critEnum.MoveNext(); } // At the end of the Crit list // The parameter list can if (match) { if (matchingMethod != null) { throw new Exception($"More then one method for {operation.ToString()} with criteria [{string.Join(",", criteriaTypes)}] on {typeof(T).FullName}"); } matchingMethod = m; } } } } return(matchingMethod); }
protected async Task <T> CallOperationMethod(PortalOperation operation, object[] criteria, Type[] criteriaTypes) { var target = Scope.Resolve <T>(); await CallOperationMethod(target, operation, criteria, criteriaTypes); return(target); }
protected async Task <T> CallOperationMethod(PortalOperation operation, bool throwException = true) { var target = Scope.Resolve <T>(); await CallOperationMethod(target, operation, throwException); return(target); }
public IEnumerable <MethodInfo> MethodsForOperation(PortalOperation operation) { if (!RegisteredOperations.TryGetValue(operation, out var methods)) { return(null); } return(methods.AsReadOnly()); }
protected async Task CallOperationMethod(T target, PortalOperation operation, bool throwException = true) { var success = await OperationManager.TryCallOperation(target, operation); if (!success && throwException) { throw new OperationMethodCallFailedException($"{operation.ToString()} method with no criteria not found on {target.GetType().FullName}."); } }
public async Task <bool> TryCallOperation(IPortalTarget target, PortalOperation operation) { await CheckAccess(operation.ToAuthorizationOperation()); var methods = MethodsForOperation(operation) ?? new List <MethodInfo>(); using (await target.StopAllActions()) { var invoked = false; foreach (var method in methods) { var success = true; var parameters = method.GetParameters().ToList(); var parameterValues = new object[parameters.Count()]; for (var i = 0; i < parameterValues.Length; i++) { var parameter = parameters[i]; if (!Scope.IsRegistered(parameter.ParameterType)) { // Assume it's a criteria not a dependency success = false; break; } } if (success) { // No parameters or all of the parameters are dependencies for (var i = 0; i < parameterValues.Length; i++) { var parameter = parameters[i]; parameterValues[i] = Scope.Resolve(parameter.ParameterType); } invoked = true; var result = method.Invoke(target, parameterValues); if (method.ReturnType == typeof(Task)) { await(Task) result; } PostOperation(target, operation); break; } } return(invoked); } }
public async Task <bool> TryCallOperation(IPortalTarget target, PortalOperation operation, object[] criteria, Type[] criteriaTypes) { await CheckAccess(operation.ToAuthorizationOperation(), criteria); using (await target.StopAllActions()) { // The criteriaTypes need to be captured by Generic method definitions // in case the values sent in are null var method = MethodForOperation(operation, criteriaTypes); if (method != null) { var parameters = method.GetParameters().ToList(); var parameterValues = new object[parameters.Count()]; var criteriaE = criteria.GetEnumerator(); for (var i = 0; i < parameterValues.Length; i++) { if (criteriaE.MoveNext()) { // Use up the criteria values first // Assume MethodForOperation got the types right parameterValues[i] = criteriaE.Current; } else { var parameter = parameters[i]; if (Scope.TryResolve(parameter.ParameterType, out var pv)) { parameterValues[i] = pv; } } } var result = method.Invoke(target, parameterValues); if (method.ReturnType == typeof(Task)) { await(Task) result; } PostOperation(target, operation); return(true); } return(false); } }
public void RegisterOperation(PortalOperation operation, MethodInfo method) { var returnType = method.ReturnType; if (!(returnType == typeof(void) || returnType == typeof(Task))) { throw new OperationMethodException($"{method.Name} must be void or return Task"); } if (!RegisteredOperations.TryGetValue(operation, out var methodList)) { RegisteredOperations.Add(operation, methodList = new List <MethodInfo>()); } methodList.Add(method); }
protected async Task CallOperationMethod(T target, PortalOperation operation, object[] criteria, Type[] criteriaTypes) { if (target == null) { throw new ArgumentNullException(nameof(target)); } if (criteria == null) { throw new ArgumentNullException(nameof(criteria)); } var success = await OperationManager.TryCallOperation(target, operation, criteria, criteriaTypes); if (!success) { throw new OperationMethodCallFailedException($"{operation.ToString()} method on {target.GetType().FullName} with criteria [{string.Join(", ", criteriaTypes.Select(x => x.FullName))}] not found."); } }
protected virtual void PostOperation(IPortalTarget target, PortalOperation operation) { var editTarget = target as IPortalEditTarget; if (editTarget != null) { switch (operation) { case PortalOperation.Create: editTarget.MarkNew(); break; case PortalOperation.CreateChild: editTarget.MarkAsChild(); editTarget.MarkNew(); break; case PortalOperation.Fetch: break; case PortalOperation.FetchChild: editTarget.MarkAsChild(); break; case PortalOperation.Delete: break; case PortalOperation.DeleteChild: break; case PortalOperation.Insert: case PortalOperation.InsertChild: case PortalOperation.Update: case PortalOperation.UpdateChild: editTarget.MarkUnmodified(); editTarget.MarkOld(); break; default: break; } } }
public PortalOperationAttributeAttribute(PortalOperation operation) { this.Operation = operation; }
public void RegisterOperation(PortalOperation operation, string methodName) { var method = typeof(T).GetMethod(methodName, System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance) ?? throw new Exception("No method found"); RegisterOperation(operation, method); }