/// <summary> /// Initializes and caches the metastate values /// necessary to invoke the method /// </summary> public void PrepForInvocation() { if (!_initialized) { lock (MethodInfo) { if (!_initialized) { DynamicMethod = DynamicMethodHandlerFactory.CreateMethod(MethodInfo); Parameters = MethodInfo.GetParameters(); TakesParamArray = (Parameters.Length == 1 && Parameters[0].ParameterType.Equals(typeof(object[]))); IsInjected = new bool[Parameters.Length]; int index = 0; foreach (var item in Parameters) { if (item.GetCustomAttributes <InjectAttribute>().Any()) { IsInjected[index] = true; } index++; } IsAsyncTask = (MethodInfo.ReturnType == typeof(Task)); IsAsyncTaskObject = (MethodInfo.ReturnType.IsGenericType && (MethodInfo.ReturnType.GetGenericTypeDefinition() == typeof(Task <>))); DataPortalMethodInfo = new DataPortalMethodInfo(MethodInfo); _initialized = true; } } } }
/// <summary> /// Called by the business object's Save() method to /// insert, update or delete an object in the database. /// </summary> /// <remarks> /// Note that this method returns a reference to the updated business object. /// If the server-side DataPortal is running remotely, this will be a new and /// different object from the original, and all object references MUST be updated /// to use this new object. /// </remarks> /// <typeparam name="T">Specific type of the business object.</typeparam> /// <param name="obj">A reference to the business object to be updated.</param> /// <returns>A reference to the updated business object.</returns> public static T Update <T>(T obj) { Server.DataPortalResult result = null; Server.DataPortalContext dpContext = null; DataPortalOperations operation = DataPortalOperations.Update; Type objectType = obj.GetType(); try { OnDataPortalInitInvoke(null); DataPortalMethodInfo method = null; var factoryInfo = ObjectFactoryAttribute.GetObjectFactoryAttribute(objectType); if (factoryInfo != null) { var factoryType = FactoryDataPortal.FactoryLoader.GetFactoryType(factoryInfo.FactoryTypeName); var bbase = obj as Core.BusinessBase; if (bbase != null && bbase.IsDeleted) { if (!Csla.Rules.BusinessRules.HasPermission(Rules.AuthorizationActions.DeleteObject, obj)) { throw new System.Security.SecurityException(string.Format(Resources.UserNotAuthorizedException, "delete", objectType.Name)); } if (factoryType != null) { method = Server.DataPortalMethodCache.GetMethodInfo(factoryType, factoryInfo.DeleteMethodName, new object[] { obj }); } } else { if (!Csla.Rules.BusinessRules.HasPermission(Rules.AuthorizationActions.EditObject, obj)) { throw new System.Security.SecurityException(string.Format(Resources.UserNotAuthorizedException, "save", objectType.Name)); } if (factoryType != null) { if (obj is Core.ICommandObject) { method = Server.DataPortalMethodCache.GetMethodInfo(factoryType, factoryInfo.ExecuteMethodName, new object[] { obj }); } else { method = Server.DataPortalMethodCache.GetMethodInfo(factoryType, factoryInfo.UpdateMethodName, new object[] { obj }); } } } if (method == null) { method = new DataPortalMethodInfo(); } } else { string methodName; if (obj is Core.ICommandObject) { methodName = "DataPortal_Execute"; operation = DataPortalOperations.Execute; if (!Csla.Rules.BusinessRules.HasPermission(Rules.AuthorizationActions.EditObject, obj)) { throw new System.Security.SecurityException(string.Format(Resources.UserNotAuthorizedException, "execute", objectType.Name)); } } else { var bbase = obj as Core.BusinessBase; if (bbase != null) { if (bbase.IsDeleted) { methodName = "DataPortal_DeleteSelf"; if (!Csla.Rules.BusinessRules.HasPermission(Rules.AuthorizationActions.DeleteObject, obj)) { throw new System.Security.SecurityException(string.Format(Resources.UserNotAuthorizedException, "delete", objectType.Name)); } } else if (bbase.IsNew) { methodName = "DataPortal_Insert"; if (!Csla.Rules.BusinessRules.HasPermission(Rules.AuthorizationActions.CreateObject, obj)) { throw new System.Security.SecurityException(string.Format(Resources.UserNotAuthorizedException, "create", objectType.Name)); } } else { methodName = "DataPortal_Update"; if (!Csla.Rules.BusinessRules.HasPermission(Rules.AuthorizationActions.EditObject, obj)) { throw new System.Security.SecurityException(string.Format(Resources.UserNotAuthorizedException, "save", objectType.Name)); } } } else { methodName = "DataPortal_Update"; if (!Csla.Rules.BusinessRules.HasPermission(Rules.AuthorizationActions.EditObject, obj)) { throw new System.Security.SecurityException(string.Format(Resources.UserNotAuthorizedException, "save", objectType.Name)); } } } method = Server.DataPortalMethodCache.GetMethodInfo(obj.GetType(), methodName); } DataPortalClient.IDataPortalProxy proxy; proxy = GetDataPortalProxy(objectType, method.RunLocal); dpContext = new Server.DataPortalContext(GetPrincipal(), proxy.IsServerRemote); OnDataPortalInvoke(new DataPortalEventArgs(dpContext, objectType, operation)); try { if (!proxy.IsServerRemote && ApplicationContext.AutoCloneOnUpdate) { // when using local data portal, automatically // clone original object before saving ICloneable cloneable = obj as ICloneable; if (cloneable != null) { obj = (T)cloneable.Clone(); } } result = proxy.Update(obj, dpContext); } catch (Server.DataPortalException ex) { result = ex.Result; if (proxy.IsServerRemote) { ApplicationContext.ContextManager.SetGlobalContext(result.GlobalContext); } throw new DataPortalException( String.Format("DataPortal.Update {0} ({1})", Resources.Failed, ex.InnerException.InnerException), ex.InnerException, result.ReturnObject); } if (proxy.IsServerRemote) { ApplicationContext.ContextManager.SetGlobalContext(result.GlobalContext); } OnDataPortalInvokeComplete(new DataPortalEventArgs(dpContext, objectType, operation)); } catch (Exception ex) { OnDataPortalInvokeComplete(new DataPortalEventArgs(dpContext, objectType, operation, ex)); throw; } return((T)result.ReturnObject); }