9using System.Globalization;
11using System.Threading.Tasks;
31 private class DataPortalAsyncRequest
33 public object Argument {
get;
set; }
34 public System.Security.Principal.IPrincipal Principal {
get;
set; }
37 public object UserState {
get;
set; }
39 public CultureInfo CurrentCulture;
40 public CultureInfo CurrentUICulture;
42 public DataPortalAsyncRequest(
object argument,
object userState)
44 this.Argument = argument;
47#pragma warning disable CS0618
49#pragma warning restore CS0618
50 this.UserState = userState;
51 this.CurrentCulture = System.Globalization.CultureInfo.CurrentCulture;
52 this.CurrentUICulture = System.Globalization.CultureInfo.CurrentUICulture;
56 private class DataPortalAsyncResult
58 public T Result {
get;
set; }
60 public object UserState {
get;
set; }
61 public Exception
Error {
get;
set; }
67 this.UserState = userState;
72 private async Task<object> DoCreateAsync(Type objectType,
object criteria,
bool isSync)
74 Server.DataPortalResult result =
null;
75 Server.DataPortalContext dpContext =
null;
78 DataPortal.OnDataPortalInitInvoke(
null);
85 Reflection.ServiceProviderMethodInfo method;
86 if (criteria is Server.EmptyCriteria)
87 method = Reflection.ServiceProviderMethodCaller.FindDataPortalMethod<CreateAttribute>(objectType,
null,
false);
89 method = Reflection.ServiceProviderMethodCaller.FindDataPortalMethod<CreateAttribute>(objectType, Server.DataPortal.GetCriteriaArray(criteria),
false);
90 var proxy = GetDataPortalProxy(objectType, method);
95 DataPortal.OnDataPortalInvoke(
new DataPortalEventArgs(dpContext, objectType, criteria,
DataPortalOperations.Create));
99 result = await proxy.Create(objectType, criteria, dpContext, isSync);
101 if (isSync && proxy.IsServerRemote)
102 ApplicationContext.ContextManager.SetGlobalContext(
GlobalContext);
104 catch (AggregateException ex)
106 if (ex.InnerExceptions.Count > 0)
108 if (ex.InnerExceptions[0] is Server.DataPortalException dpe)
109 HandleCreateDataPortalException(dpe, isSync, proxy);
111 throw new DataPortalException(
115 catch (Server.DataPortalException ex)
117 HandleCreateDataPortalException(ex, isSync, proxy);
119 DataPortal.OnDataPortalInvokeComplete(
new DataPortalEventArgs(dpContext, objectType, criteria,
DataPortalOperations.Create));
123 DataPortal.OnDataPortalInvokeComplete(
new DataPortalEventArgs(dpContext, objectType, criteria,
DataPortalOperations.Create, ex));
126 return result.ReturnObject;
131 HandleDataPortalException(
"Create", ex, isSync, proxy);
141 public T
Create(params
object[] criteria)
143 return (T)
Create(typeof(T), Server.DataPortal.GetCriteriaFromArray(criteria));
146 internal static object Create(Type objectType,
object criteria)
151 return dp.DoCreateAsync(objectType, criteria,
true).Result;
153 catch (AggregateException ex)
155 if (ex.InnerExceptions.Count > 0)
156 throw ex.InnerExceptions[0];
170 return (T)await DoCreateAsync(typeof(T), Server.DataPortal.GetCriteriaFromArray(criteria),
false);
259 catch (AggregateException ex)
261 if (ex.InnerExceptions.Count > 0)
272 private async Task<object> DoFetchAsync(Type objectType,
object criteria,
bool isSync)
274 Server.DataPortalResult result =
null;
275 Server.DataPortalContext dpContext =
null;
286 var method = Reflection.ServiceProviderMethodCaller.FindDataPortalMethod<
FetchAttribute>(objectType, Server.DataPortal.GetCriteriaArray(criteria),
false);
287 var proxy = GetDataPortalProxy(objectType, method);
296 result = await proxy.Fetch(objectType, criteria, dpContext, isSync);
298 if (isSync && proxy.IsServerRemote)
299 ApplicationContext.ContextManager.SetGlobalContext(
GlobalContext);
301 catch (AggregateException ex)
303 if (ex.InnerExceptions.Count > 0)
305 var dpe = ex.InnerExceptions[0] as Server.DataPortalException;
307 HandleFetchDataPortalException(dpe, isSync, proxy);
309 throw new DataPortalException(
313 catch (Server.DataPortalException ex)
315 HandleFetchDataPortalException(ex, isSync, proxy);
317 DataPortal.OnDataPortalInvokeComplete(
new DataPortalEventArgs(dpContext, objectType, criteria,
DataPortalOperations.Fetch));
321 DataPortal.OnDataPortalInvokeComplete(
new DataPortalEventArgs(dpContext, objectType, criteria,
DataPortalOperations.Fetch, ex));
324 return result.ReturnObject;
329 HandleDataPortalException(
"Fetch", ex, isSync, proxy);
387 public T
Fetch(params
object[] criteria)
389 return (T)Fetch(typeof(T), Server.DataPortal.GetCriteriaFromArray(criteria));
392 internal static object Fetch(Type objectType,
object criteria)
397 return dp.DoFetchAsync(objectType, criteria,
true).Result;
399 catch (AggregateException ex)
401 if (ex.InnerExceptions.Count > 0)
402 throw ex.InnerExceptions[0];
416 return (T)await DoFetchAsync(typeof(T), Server.DataPortal.GetCriteriaFromArray(criteria),
false);
450 public async
void BeginFetch(
object criteria,
object userState)
457 catch (AggregateException ex)
459 if (ex.InnerExceptions.Count > 0)
470 internal async Task<T> DoUpdateAsync(T obj,
bool isSync)
472 Server.DataPortalResult result =
null;
473 Server.DataPortalContext dpContext =
null;
475 Type objectType = obj.GetType();
479 DataPortalClient.IDataPortalProxy proxy =
null;
481 if (factoryInfo !=
null)
486 if (obj is Core.ICommandObject)
492 if (factoryType !=
null)
493 method = Server.DataPortalMethodCache.GetMethodInfo(factoryType, factoryInfo.ExecuteMethodName,
new object[] { obj });
497 if (obj is Core.BusinessBase bbase)
505 if (factoryType !=
null)
506 method = Server.DataPortalMethodCache.GetMethodInfo(factoryType, factoryInfo.DeleteMethodName,
507 new object[] { obj });
510 else if (bbase.IsNew)
516 if (factoryType !=
null)
517 method = Server.DataPortalMethodCache.GetMethodInfo(factoryType, factoryInfo.UpdateMethodName,
518 new object[] { obj });
526 if (factoryType !=
null)
527 method = Server.DataPortalMethodCache.GetMethodInfo(factoryType, factoryInfo.UpdateMethodName,
528 new object[] { obj });
538 if (factoryType !=
null)
539 method = Server.DataPortalMethodCache.GetMethodInfo(factoryType, factoryInfo.UpdateMethodName,
540 new object[] { obj });
545 proxy = GetDataPortalProxy(objectType, method.RunLocal);
549 Reflection.ServiceProviderMethodInfo method;
550 var criteria = Server.DataPortal.GetCriteriaArray(Server.EmptyCriteria.Instance);
551 if (obj is Core.ICommandObject)
558 method = Reflection.ServiceProviderMethodCaller.FindDataPortalMethod<ExecuteAttribute>(objectType, criteria,
false);
562 if (obj is Core.BusinessBase bbase)
570 method = Reflection.ServiceProviderMethodCaller.FindDataPortalMethod<DeleteSelfAttribute>(objectType, criteria,
false);
572 else if (bbase.IsNew)
578 method = Reflection.ServiceProviderMethodCaller.FindDataPortalMethod<InsertAttribute>(objectType, criteria,
false);
586 method = Reflection.ServiceProviderMethodCaller.FindDataPortalMethod<UpdateAttribute>(objectType, criteria,
false);
591 method = Reflection.ServiceProviderMethodCaller.FindDataPortalMethod<UpdateAttribute>(objectType, criteria,
false);
594 proxy = GetDataPortalProxy(objectType, method);
598 new Server.DataPortalContext(GetPrincipal(), proxy.IsServerRemote);
600 DataPortal.OnDataPortalInvoke(
new DataPortalEventArgs(dpContext, objectType, obj, operation));
604 if (!proxy.IsServerRemote && ApplicationContext.AutoCloneOnUpdate)
608 if (obj is ICloneable cloneable)
609 obj = (T)cloneable.Clone();
611 result = await proxy.Update(obj, dpContext, isSync);
613 catch (AggregateException ex)
615 if (ex.InnerExceptions.Count > 0)
617 if (ex.InnerExceptions[0] is Server.DataPortalException dpe)
618 HandleUpdateDataPortalException(dpe, isSync, proxy);
620 throw new DataPortalException(
624 catch (Server.DataPortalException ex)
626 HandleUpdateDataPortalException(ex, isSync, proxy);
630 if (proxy.IsServerRemote && isSync)
631 ApplicationContext.ContextManager.SetGlobalContext(
GlobalContext);
633 DataPortal.OnDataPortalInvokeComplete(
new DataPortalEventArgs(dpContext, objectType, obj, operation));
637 DataPortal.OnDataPortalInvokeComplete(
new DataPortalEventArgs(dpContext, objectType, obj, operation, ex));
640 return (T)result.ReturnObject;
645 HandleDataPortalException(
"Update", ex, isSync, proxy);
650 var result = ex.Result;
652 if (proxy.IsServerRemote && isSync)
653 ApplicationContext.ContextManager.SetGlobalContext(
GlobalContext);
654 var original = ex.InnerException;
655 if (original.InnerException !=
null)
656 original = original.InnerException;
657 throw new DataPortalException(
659 ex.InnerException, result.ReturnObject);
719 return DoUpdateAsync(obj,
true).Result;
721 catch (AggregateException ex)
723 if (ex.InnerExceptions.Count > 0)
724 throw ex.InnerExceptions[0];
755 catch (AggregateException ex)
757 if (ex.InnerExceptions.Count > 0)
775 return await DoUpdateAsync(obj,
false);
778 internal async Task DoDeleteAsync(Type objectType,
object criteria,
bool isSync)
780 Server.DataPortalResult result =
null;
781 Server.DataPortalContext dpContext =
null;
791 var method = Reflection.ServiceProviderMethodCaller.FindDataPortalMethod<
DeleteAttribute>(objectType, Server.DataPortal.GetCriteriaArray(criteria),
false);
792 var proxy = GetDataPortalProxy(objectType, method);
794 dpContext =
new Server.DataPortalContext(GetPrincipal(), proxy.IsServerRemote);
800 result = await proxy.Delete(objectType, criteria, dpContext, isSync);
802 catch (AggregateException ex)
804 if (ex.InnerExceptions.Count > 0)
806 var dpe = ex.InnerExceptions[0] as Server.DataPortalException;
808 HandleDeleteDataPortalException(dpe, isSync, proxy);
810 throw new DataPortalException(
814 catch (Server.DataPortalException ex)
816 HandleDeleteDataPortalException(ex, isSync, proxy);
820 if (proxy.IsServerRemote && isSync)
821 ApplicationContext.ContextManager.SetGlobalContext(result.GlobalContext);
823 DataPortal.OnDataPortalInvokeComplete(
new DataPortalEventArgs(dpContext, objectType, criteria,
DataPortalOperations.Delete));
827 DataPortal.OnDataPortalInvokeComplete(
new DataPortalEventArgs(dpContext, objectType, criteria,
DataPortalOperations.Delete, ex));
834 HandleDataPortalException(
"Delete", ex, isSync, proxy);
890 public void Delete(params
object[] criteria)
892 Delete(typeof(T), Server.DataPortal.GetCriteriaFromArray(criteria));
895 internal static void Delete(Type objectType,
object criteria)
900 var task = dp.DoDeleteAsync(objectType, criteria,
true);
901 if (!task.IsCompleted)
902 task.RunSynchronously();
903 if (task.Exception !=
null)
904 throw task.Exception;
906 catch (AggregateException ex)
908 if (ex.InnerExceptions.Count > 0)
909 throw ex.InnerExceptions[0];
937 await DoDeleteAsync(typeof(T), criteria,
true);
940 catch (AggregateException ex)
942 if (ex.InnerExceptions.Count > 0)
960 await DoDeleteAsync(typeof(T), Server.DataPortal.GetCriteriaFromArray(criteria),
false);
1014 catch (AggregateException ex)
1016 if (ex.InnerExceptions.Count > 0)
1021 catch (Exception ex)
1034 return await DoUpdateAsync(command,
false);
1037 private static DataPortalClient.IDataPortalProxy GetDataPortalProxy(Type objectType, Reflection.ServiceProviderMethodInfo method)
1040 return GetDataPortalProxy(objectType, method.MethodInfo.RunLocal());
1042 return GetDataPortalProxy(objectType,
false);
1045 private static DataPortalClient.IDataPortalProxy GetDataPortalProxy(Type objectType,
bool forceLocal)
1047 if (forceLocal || ApplicationContext.IsOffline)
1049 return new DataPortalClient.LocalProxy();
1054 if (DataPortal.ProxyFactory ==
null)
1055 DataPortal.LoadDataPortalProxyFactory();
1057 return DataPortal.ProxyFactory.Create(objectType);
1061 private static System.Security.Principal.IPrincipal GetPrincipal()
1063 if (ApplicationContext.AuthenticationType ==
"Windows")
1071 return ApplicationContext.User;
1076 internal static class Extensions
1078 internal static bool RunLocal(
this System.Reflection.MethodInfo t)
1080 return t.CustomAttributes.Count(a => a.AttributeType.Equals(typeof(RunLocalAttribute))) > 0;
Dictionary type that is serializable with the SerializationFormatterFactory.GetFormatter().
Provides information about the DataPortal call.
This is the client-side DataPortal.
void BeginCreate(object criteria)
Called by a factory method in a business class or by the UI to create a new object,...
async void BeginExecute(T command, object userState)
Called by a factory method in a business class or by the UI to execute a command object.
async void BeginFetch(object criteria, object userState)
Called by a factory method in a business class or by the UI to Fetch a new object,...
void Delete(params object[] criteria)
Called by a factory method in a business class or by the UI to delete an object.
virtual void OnCreateCompleted(DataPortalResult< T > e)
Raises the event.
T Execute(T command)
Called by a factory method in a business class or by the UI to execute a command object.
async void BeginUpdate(T obj, object userState)
Called by a factory method in a business class or by the UI to update an object.
virtual void OnUpdateCompleted(DataPortalResult< T > e)
Raises the event.
async Task< T > CreateAsync(params object[] criteria)
Called by a factory method in a business class or by the UI to create a new object,...
virtual void OnExecuteCompleted(DataPortalResult< T > e)
Raises the ExecuteCompleted event.
async Task DeleteAsync(params object[] criteria)
Called by a factory method in a business class or by the UI to delete an object.
EventHandler< DataPortalResult< T > > FetchCompleted
Event raised when the operation has completed.
EventHandler< DataPortalResult< T > > DeleteCompleted
Event raised when the operation has completed.
void BeginExecute(T command)
Called by a factory method in a business class or by the UI to execute a command object.
T Update(T obj)
Called by a factory method in a business class or by the UI to update an object.
void BeginUpdate(T obj)
Called by a factory method in a business class or by the UI to update an object.
T Create(params object[] criteria)
Called by a factory method in a business class to create a new object, which is loaded with default v...
virtual void OnDeleteCompleted(DataPortalResult< T > e)
Raises the event.
async Task< T > ExecuteAsync(T command)
Called by a factory method in a business class or by the UI to execute a command object.
virtual void OnFetchCompleted(DataPortalResult< T > e)
Raises the event.
EventHandler< DataPortalResult< T > > UpdateCompleted
Event raised when the operation has completed.
EventHandler< DataPortalResult< T > > ExecuteCompleted
Event indicating an execute operation is complete.
T Fetch(params object[] criteria)
Called by a factory method in a business class to Fetch a new object, which is loaded with default va...
void BeginFetch()
Called by a factory method in a business class or by the UI to Fetch a new object,...
Csla.Core.ContextDictionary GlobalContext
Gets a reference to the global context returned from the background thread and/or server.
async Task< T > UpdateAsync(T obj)
Called by a factory method in a business class or by the UI to update an object.
void BeginCreate()
Called by a factory method in a business class or by the UI to create a new object,...
EventHandler< DataPortalResult< T > > CreateCompleted
Event raised when the operation has completed.
static object Create(Type objectType, object criteria)
Called by a factory method in a business class to create a new object, which is loaded with default v...
async void BeginCreate(object criteria, object userState)
Called by a factory method in a business class or by the UI to create a new object,...
async Task< T > FetchAsync(params object[] criteria)
Called by a factory method in a business class or by the UI to Fetch a new object,...
void BeginDelete(object criteria)
Called by a factory method in a business class or by the UI to delete an object.
void BeginFetch(object criteria)
Called by a factory method in a business class or by the UI to Fetch a new object,...
async void BeginDelete(object criteria, object userState)
Called by a factory method in a business class or by the UI to delete an object.
DataPortalResult defines the results of DataPortal operation.
Specifies a method used by the server-side data portal to delete domain object data during an update ...
Specifies a method used by the server-side data portal to load existing data into the domain object.
A strongly-typed resource class, for looking up localized strings, etc.
static string Failed
Looks up a localized string similar to failed.
static string UserNotAuthorizedException
Looks up a localized string similar to User not authorized to {0} object type {1}.
Tracks the business rules for a business object.
static bool HasPermission(AuthorizationActions action, Type objectType)
Checks per-type authorization rules.
Provides consistent context information between the client and server DataPortal objects.
Server-side data portal implementation that invokes an object factory rather than directly interactin...
static IObjectFactoryLoader FactoryLoader
Gets or sets a delegate reference to the method called to create instances of factory objects as requ...
Specifies that the data portal should invoke a factory object rather than the business object.
Interface implemented by client-side data portal proxy objects.
Interface defining the members of the data portal type.
Type GetFactoryType(string factoryName)
Returns the type of the factory object.
@ Error
Represents a serious business rule violation that should cause an object to be considered invalid.
DataPortalOperations
List of data portal operations.