/// <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;
                    }
                }
            }
        }
示例#2
0
        /// <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);
        }