示例#1
0
        /// <summary>
        /// Allows late bound invocation of
        /// properties and methods.
        /// </summary>
        /// <param name="target">Object implementing the property or method.</param>
        /// <param name="methodName">Name of the property or method.</param>
        /// <param name="callType">Specifies how to invoke the property or method.</param>
        /// <param name="args">List of arguments to pass to the method.</param>
        /// <returns>The result of the property or method invocation.</returns>
        public static object CallByName(
            object target, string methodName, CallType callType,
            params object[] args)
        {
            switch (callType)
            {
            case CallType.Get:
            {
                return(MethodCaller.CallPropertyGetter(target, methodName));
            }

            case CallType.Let:
            case CallType.Set:
            {
                MethodCaller.CallPropertySetter(target, methodName, args[0]);
                return(null);
            }

            case CallType.Method:
            {
                return(MethodCaller.CallMethod(target, methodName, args));
            }
            }
            return(null);
        }
示例#2
0
 /// <summary>
 /// Throws an exception if a synchronous data portal call is trying to invoke an asynchronous method on the client.
 /// </summary>
 /// <param name="isSync">True if the client-side proxy should synchronously invoke the server.</param>
 /// <param name="obj">Object containing method.</param>
 /// <param name="methodName">Name of the method.</param>
 /// <param name="parameters">
 /// Parameters to pass to method.
 /// </param>
 internal static void ThrowIfAsyncMethodOnSyncClient(bool isSync, object obj, string methodName, params object[] parameters)
 {
     if (isSync &&
         ApplicationContext.ExecutionLocation != ApplicationContext.ExecutionLocations.Server &&
         MethodCaller.IsAsyncMethod(obj, methodName, parameters))
     {
         throw new NotSupportedException(string.Format(Resources.AsyncMethodOnSyncClientNotAllowed, methodName));
     }
 }
示例#3
0
 internal static void ThrowIfAsyncMethodOnSyncClient(bool isSync, System.Reflection.MethodInfo method)
 {
     if (isSync &&
         ApplicationContext.ExecutionLocation != ApplicationContext.ExecutionLocations.Server &&
         MethodCaller.IsAsyncMethod(method))
     {
         throw new NotSupportedException(string.Format(Resources.AsyncMethodOnSyncClientNotAllowed, method.Name));
     }
 }
示例#4
0
 /// <summary>
 /// Loads the data portal factory.
 /// </summary>
 private static void LoadDataPortalProxyFactory()
 {
     if (_dataProxyFactory == null)
     {
         if (String.IsNullOrEmpty(ApplicationContext.DataPortalProxyFactory) || ApplicationContext.DataPortalProxyFactory == "Default")
         {
             _dataProxyFactory = new DataPortalClient.DefaultPortalProxyFactory();
         }
         else
         {
             var proxyFactoryType = Type.GetType(ApplicationContext.DataPortalProxyFactory, true, true);
             _dataProxyFactory = (DataPortalClient.IDataPortalProxyFactory)MethodCaller.CreateInstance(proxyFactoryType);
         }
     }
 }
示例#5
0
        /// <summary>
        /// Gets a reference to the DataPortal_Fetch method for
        /// the specified business object type.
        /// </summary>
        /// <param name="objectType">Type of the business object.</param>
        /// <param name="criteria">Criteria parameter value.</param>
        /// <remarks>
        /// If the criteria parameter value is an integer, that is a special
        /// flag indicating that the parameter should be considered missing
        /// (not Nothing/null - just not there).
        /// </remarks>
        public static MethodInfo GetFetchMethod(Type objectType, object criteria)
        {
            MethodInfo method = null;

            if (criteria is int)
            {
                // an "Integer" criteria is a special flag indicating
                // that criteria is empty and should not be used
                method = MethodCaller.GetMethod(objectType, "DataPortal_Fetch");
            }
            else
            {
                method = MethodCaller.GetMethod(objectType, "DataPortal_Fetch", criteria);
            }
            return(method);
        }
示例#6
0
        /// <summary>
        /// Loads the data portal factory.
        /// </summary>
        internal static void LoadDataPortalProxyFactory()
        {
            if (_dataProxyFactory == null)
            {
                if (String.IsNullOrEmpty(ApplicationContext.DataPortalProxyFactory) || ApplicationContext.DataPortalProxyFactory == "Default")
                {
                    _dataProxyFactory = new DataPortalClient.DataPortalProxyFactory();
                }
                else
                {
                    var proxyFactoryType =
                        Type.GetType(ApplicationContext.DataPortalProxyFactory) ??
                        throw new InvalidOperationException(
                                  string.Format(Resources.UnableToLoadDataPortalProxyFactory, ApplicationContext.DataPortalProxyFactory));

                    _dataProxyFactory = (DataPortalClient.IDataPortalProxyFactory)MethodCaller.CreateInstance(proxyFactoryType);
                }
            }
        }
        private static object Fetch(Type objectType, object criteria)
        {
            Server.DataPortalResult result;

            MethodInfo method = MethodCaller.GetMethod(
                objectType, "DataPortal_Fetch", criteria);

            DataPortalClient.IDataPortalProxy proxy;
            proxy = GetDataPortalProxy(RunLocal(method));

            Server.DataPortalContext dpContext =
                new Server.DataPortalContext(GetPrincipal(),
                                             proxy.IsServerRemote);

            OnDataPortalInvoke(new DataPortalEventArgs(dpContext));

            try
            {
                result = proxy.Fetch(objectType, criteria, dpContext);
            }
            catch (Server.DataPortalException ex)
            {
                result = ex.Result;
                if (proxy.IsServerRemote)
                {
                    ApplicationContext.SetGlobalContext(result.GlobalContext);
                }
                throw new DataPortalException("DataPortal.Fetch " +
                                              Resources.Failed, ex.InnerException, result.ReturnObject);
            }



            if (proxy.IsServerRemote)
            {
                ApplicationContext.SetGlobalContext(result.GlobalContext);
            }

            OnDataPortalInvokeComplete(new DataPortalEventArgs(dpContext));

            return(result.ReturnObject);
        }
示例#8
0
        public static void Delete(object criteria)
        {
            Server.DataPortalResult result;

            MethodInfo method = MethodCaller.GetMethod(
                MethodCaller.GetObjectType(criteria), "DataPortal_Delete", criteria);

            DataPortalClient.IDataPortalProxy proxy;
            proxy = GetDataPortalProxy(RunLocal(method));

            Server.DataPortalContext dpContext = new Server.DataPortalContext(GetPrincipal(), proxy.IsServerRemote);

            OnDataPortalInvoke(new DataPortalEventArgs(dpContext));

            try
            {
                result = proxy.Delete(criteria, dpContext);
            }
            catch (Server.DataPortalException ex)
            {
                result = ex.Result;
                if (proxy.IsServerRemote)
                {
                    ApplicationContext.SetGlobalContext(result.GlobalContext);
                }
                throw new DataPortalException(
                          String.Format("DataPortal.Delete {0} ({1})", Resources.Failed, ex.InnerException.InnerException),
                          ex.InnerException, result.ReturnObject);
            }

            if (proxy.IsServerRemote)
            {
                ApplicationContext.SetGlobalContext(result.GlobalContext);
            }

            OnDataPortalInvokeComplete(new DataPortalEventArgs(dpContext));
        }
示例#9
0
        /// <summary>
        /// Saves the specified item in the list.
        /// </summary>
        /// <param name="index">Index of item to be saved.</param>
        /// <param name="delete">true if the item should be deleted.</param>
        protected virtual async Task SaveItemAsync(int index, bool delete)
        {
            T   item       = this[index];
            var handleBusy = false;

            if ((item.IsDeleted || delete) || (item.IsValid && item.IsDirty))
            {
                T savable = item;

                // attempt to clone object
                ICloneable cloneable = savable as ICloneable;
                if (cloneable != null)
                {
                    savable = (T)cloneable.Clone();
                    MethodCaller.CallMethodIfImplemented(item, "MarkBusy");
                    handleBusy = true;
                }

                // commit all changes
                int editLevel = savable.EditLevel;
                for (int tmp = 1; tmp <= editLevel; tmp++)
                {
                    savable.AcceptChanges(editLevel - tmp, false);
                }

                if (delete)
                {
                    savable.Delete();
                }

                Exception error  = null;
                T         result = default(T);
                var       dp     = ApplicationContext.CreateInstance <DataPortal <T> >();
                try
                {
                    result = await dp.UpdateAsync((T)savable);
                }
                catch (AggregateException ex)
                {
                    if (ex.InnerExceptions.Count > 0)
                    {
                        error = ex.InnerExceptions[0];
                    }
                    else
                    {
                        error = ex;
                    }
                }
                catch (Exception ex)
                {
                    error = ex;
                }
                finally
                {
                    if (handleBusy)
                    {
                        MethodCaller.CallMethodIfImplemented(item, "MarkIdle");
                    }
                }
                // update index - this may have changed under the duration of async call
                index = IndexOf(item);
                if (error == null && result != null)
                {
                    if (savable.IsDeleted)
                    {
                        //SafeRemoveItem  will raise INotifyCollectionChanged event
                        SafeRemoveItem(index);
                    }
                    else
                    {
                        for (int tmp = 1; tmp <= editLevel; tmp++)
                        {
                            result.CopyState(tmp, false);
                        }

                        SafeSetItem(index, result);
                        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
                        OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, this[index], index));
                    }
                    item.SaveComplete(result);
                    OnSaved(result, null);
                }
                else
                {
                    item.SaveComplete(item);
                    OnSaved(item, error);
                }
            }
        }
示例#10
0
 public static object Create(object criteria)
 {
     return(Create(MethodCaller.GetObjectType(criteria), criteria));
 }
示例#11
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>
        /// <param name="obj">A reference to the business object to be updated.</param>
        /// <returns>A reference to the updated business object.</returns>
        public static object Update(object obj)
        {
            Server.DataPortalResult result;

            MethodInfo method;
            string     methodName;

            if (obj is CommandBase)
            {
                methodName = "DataPortal_Execute";
            }
            else if (obj is Core.BusinessBase)
            {
                Core.BusinessBase tmp = (Core.BusinessBase)obj;
                if (tmp.IsDeleted)
                {
                    methodName = "DataPortal_DeleteSelf";
                }
                else
                if (tmp.IsNew)
                {
                    methodName = "DataPortal_Insert";
                }
                else
                {
                    methodName = "DataPortal_Update";
                }
            }
            else
            {
                methodName = "DataPortal_Update";
            }

            method = MethodCaller.GetMethod(obj.GetType(), methodName);

            DataPortalClient.IDataPortalProxy proxy;
            proxy = GetDataPortalProxy(RunLocal(method));

            Server.DataPortalContext dpContext =
                new Server.DataPortalContext(GetPrincipal(), proxy.IsServerRemote);

            OnDataPortalInvoke(new DataPortalEventArgs(dpContext));

            try
            {
                result = proxy.Update(obj, dpContext);
            }
            catch (Server.DataPortalException ex)
            {
                result = ex.Result;
                if (proxy.IsServerRemote)
                {
                    ApplicationContext.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.SetGlobalContext(result.GlobalContext);
            }

            OnDataPortalInvokeComplete(new DataPortalEventArgs(dpContext));

            return(result.ReturnObject);
        }
示例#12
0
 /// <summary>
 /// Called by a factory method in a business class to retrieve
 /// an object, which is loaded with values from the database.
 /// </summary>
 /// <param name="criteria">Object-specific criteria.</param>
 /// <returns>An object populated with values from the database.</returns>
 public static object Fetch(object criteria)
 {
     return(Fetch(MethodCaller.GetObjectType(criteria), criteria));
 }
示例#13
0
        /// <summary>
        /// Saves the specified item in the list.
        /// </summary>
        /// <param name="index">
        /// Index of the item to be saved.
        /// </param>
        /// <remarks>
        /// This method properly saves the child item,
        /// by making sure the item in the collection
        /// is properly replaced by the result of the
        /// Save() method call.
        /// </remarks>
        public virtual void SaveItem(int index)
        {
            T   item       = this[index];
            var handleBusy = false;

            if (item.IsDeleted || (item.IsValid && item.IsDirty))
            {
                T savable = item;

                // attempt to clone object
                ICloneable cloneable = savable as ICloneable;
                if (cloneable != null)
                {
                    savable = (T)cloneable.Clone();
                    MethodCaller.CallMethodIfImplemented(item, "MarkBusy");
                    handleBusy = true;
                }

                // commit all changes
                int editLevel = savable.EditLevel;
                for (int tmp = 1; tmp <= editLevel; tmp++)
                {
                    savable.AcceptChanges(editLevel - tmp, false);
                }

                // save object
                DataPortal <T> dp = new DataPortal <T>();
                dp.UpdateCompleted += (o, e) =>
                {
                    if (handleBusy)
                    {
                        MethodCaller.CallMethodIfImplemented(item, "MarkIdle");
                    }
                    if (e.Error == null)
                    {
                        T result = e.Object;
                        if (item.IsDeleted)
                        {
                            //SafeRemoveItem  will raise INotifyCollectionChanged event
                            SafeRemoveItem(index);
                        }
                        else
                        {
                            for (int tmp = 1; tmp <= editLevel; tmp++)
                            {
                                result.CopyState(tmp, false);
                            }

                            SafeSetItem(index, result);
#if SILVERLIGHT
                            //Because SL Data Grid does not support replace action.
                            // we have to artificially raise remove/insert events
                            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Remove, item, index));
                            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Add, this[index], index));
#else
                            OnCollectionChanged(new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Replace, result, item));
#endif
                        }
#if SILVERLIGHT
                        item.SaveComplete(result, null, null);
#else
                        item.SaveComplete(result);
#endif
                        OnSaved(result, null);
                    }
                    else
                    {
#if SILVERLIGHT
                        item.SaveComplete(item, e.Error, null);
#else
                        item.SaveComplete(item);
#endif
                        OnSaved(item, e.Error);
                    }
                };
                dp.BeginUpdate(savable);
            }
        }