/// <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); }
/// <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)); } }
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)); } }
/// <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); } } }
/// <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); }
/// <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); }
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)); }
/// <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); } } }
public static object Create(object criteria) { return(Create(MethodCaller.GetObjectType(criteria), criteria)); }
/// <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); }
/// <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)); }
/// <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); } }