Commit for development environment setup

This commit is contained in:
2023-06-19 16:12:33 -04:00
parent be72063a3c
commit bbce2ad0a6
2209 changed files with 1171775 additions and 625 deletions

View File

@@ -0,0 +1,73 @@
using System;
using System.Security.Permissions;
namespace Csla.Server
{
/// <summary>
/// This exception is returned from the
/// CallMethod method in the server-side DataPortal
/// and contains the exception thrown by the
/// underlying business object method that was
/// being invoked.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors")]
[Serializable()]
public class CallMethodException : Exception
{
private string _innerStackTrace;
/// <summary>
/// Get the stack trace from the original
/// exception.
/// </summary>
/// <value></value>
/// <returns></returns>
/// <remarks></remarks>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)")]
public override string StackTrace
{
get
{
return string.Format("{0}{1}{2}",
_innerStackTrace, Environment.NewLine, base.StackTrace);
}
}
/// <summary>
/// Creates an instance of the object.
/// </summary>
/// <param name="message">Message text describing the exception.</param>
/// <param name="ex">Inner exception object.</param>
public CallMethodException(string message, Exception ex)
: base(message, ex)
{
_innerStackTrace = ex.StackTrace;
}
/// <summary>
/// Creates an instance of the object for deserialization.
/// </summary>
/// <param name="info">Serialization info.</param>
/// <param name="context">Serialiation context.</param>
protected CallMethodException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
: base(info, context)
{
_innerStackTrace = info.GetString("_innerStackTrace");
}
/// <summary>
/// Serializes the object.
/// </summary>
/// <param name="info">Serialization info.</param>
/// <param name="context">Serialization context.</param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")]
[SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.SerializationFormatter)]
[SecurityPermission(SecurityAction.Demand, Flags = SecurityPermissionFlag.SerializationFormatter)]
public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue("_innerStackTrace", _innerStackTrace);
}
}
}

View File

@@ -0,0 +1,327 @@
using System;
using System.Reflection;
using System.Security.Principal;
using System.Collections.Specialized;
using Csla.Properties;
namespace Csla.Server
{
/// <summary>
/// Implements the server-side DataPortal
/// message router as discussed
/// in Chapter 4.
/// </summary>
public class DataPortal : IDataPortalServer
{
#region Data Access
/// <summary>
/// Create a new business object.
/// </summary>
/// <param name="objectType">Type of business object to create.</param>
/// <param name="criteria">Criteria object describing business object.</param>
/// <param name="context">
/// <see cref="Server.DataPortalContext" /> object passed to the server.
/// </param>
public DataPortalResult Create(
Type objectType, object criteria, DataPortalContext context)
{
try
{
SetContext(context);
DataPortalResult result;
MethodInfo method = MethodCaller.GetCreateMethod(objectType, criteria);
IDataPortalServer portal;
switch (TransactionalType(method))
{
case TransactionalTypes.EnterpriseServices:
portal = new ServicedDataPortal();
try
{
result = portal.Create(objectType, criteria, context);
}
finally
{
((ServicedDataPortal)portal).Dispose();
}
break;
case TransactionalTypes.TransactionScope:
portal = new TransactionalDataPortal();
result = portal.Create(objectType, criteria, context);
break;
default:
portal = new SimpleDataPortal();
result = portal.Create(objectType, criteria, context);
break;
}
return result;
}
finally
{
ClearContext(context);
}
}
/// <summary>
/// Get an existing business object.
/// </summary>
/// <param name="objectType">Type of business object to retrieve.</param>
/// <param name="criteria">Criteria object describing business object.</param>
/// <param name="context">
/// <see cref="Server.DataPortalContext" /> object passed to the server.
/// </param>
public DataPortalResult Fetch(Type objectType, object criteria, DataPortalContext context)
{
try
{
SetContext(context);
DataPortalResult result;
MethodInfo method = MethodCaller.GetFetchMethod(objectType, criteria);
IDataPortalServer portal;
switch (TransactionalType(method))
{
case TransactionalTypes.EnterpriseServices:
portal = new ServicedDataPortal();
try
{
result = portal.Fetch(objectType, criteria, context);
}
finally
{
((ServicedDataPortal)portal).Dispose();
}
break;
case TransactionalTypes.TransactionScope:
portal = new TransactionalDataPortal();
result = portal.Fetch(objectType, criteria, context);
break;
default:
portal = new SimpleDataPortal();
result = portal.Fetch(objectType, criteria, context);
break;
}
return result;
}
finally
{
ClearContext(context);
}
}
/// <summary>
/// Update a business object.
/// </summary>
/// <param name="obj">Business object to update.</param>
/// <param name="context">
/// <see cref="Server.DataPortalContext" /> object passed to the server.
/// </param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")]
public DataPortalResult Update(object obj, DataPortalContext context)
{
try
{
SetContext(context);
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);
IDataPortalServer portal;
switch (TransactionalType(method))
{
case TransactionalTypes.EnterpriseServices:
portal = new ServicedDataPortal();
try
{
result = portal.Update(obj, context);
}
finally
{
((ServicedDataPortal)portal).Dispose();
}
break;
case TransactionalTypes.TransactionScope:
portal = new TransactionalDataPortal();
result = portal.Update(obj, context);
break;
default:
portal = new SimpleDataPortal();
result = portal.Update(obj, context);
break;
}
return result;
}
finally
{
ClearContext(context);
}
}
/// <summary>
/// Delete a business object.
/// </summary>
/// <param name="criteria">Criteria object describing business object.</param>
/// <param name="context">
/// <see cref="Server.DataPortalContext" /> object passed to the server.
/// </param>
public DataPortalResult Delete(object criteria, DataPortalContext context)
{
try
{
SetContext(context);
DataPortalResult result;
MethodInfo method = MethodCaller.GetMethod(
MethodCaller.GetObjectType(criteria), "DataPortal_Delete", criteria);
IDataPortalServer portal;
switch (TransactionalType(method))
{
case TransactionalTypes.EnterpriseServices:
portal = new ServicedDataPortal();
try
{
result = portal.Delete(criteria, context);
}
finally
{
((ServicedDataPortal)portal).Dispose();
}
break;
case TransactionalTypes.TransactionScope:
portal = new TransactionalDataPortal();
result = portal.Delete(criteria, context);
break;
default:
portal = new SimpleDataPortal();
result = portal.Delete(criteria, context);
break;
}
return result;
}
finally
{
ClearContext(context);
}
}
#endregion
#region Context
private static void SetContext(DataPortalContext context)
{
// if the dataportal is not remote then
// do nothing
if (!context.IsRemotePortal) return;
// set the context value so everyone knows the
// code is running on the server
ApplicationContext.SetExecutionLocation(ApplicationContext.ExecutionLocations.Server);
// set the app context to the value we got from the
// client
ApplicationContext.SetContext(context.ClientContext, context.GlobalContext);
// set the thread's culture to match the client
System.Threading.Thread.CurrentThread.CurrentCulture =
new System.Globalization.CultureInfo(context.ClientCulture);
System.Threading.Thread.CurrentThread.CurrentUICulture =
new System.Globalization.CultureInfo(context.ClientUICulture);
if (ApplicationContext.AuthenticationType == "Windows")
{
// When using integrated security, Principal must be null
if (context.Principal == null)
{
// Set .NET to use integrated security
AppDomain.CurrentDomain.SetPrincipalPolicy(PrincipalPolicy.WindowsPrincipal);
return;
}
else
{
throw new System.Security.SecurityException(Resources.NoPrincipalAllowedException);
}
}
// We expect the Principal to be of the type BusinesPrincipal
if (context.Principal != null)
{
if (context.Principal is Security.BusinessPrincipalBase)
ApplicationContext.User = context.Principal;
else
throw new System.Security.SecurityException(
Resources.BusinessPrincipalException + " " +
((object)context.Principal).ToString());
}
else
throw new System.Security.SecurityException(
Resources.BusinessPrincipalException + " Nothing");
}
private static void ClearContext(DataPortalContext context)
{
// if the dataportal is not remote then
// do nothing
if (!context.IsRemotePortal) return;
ApplicationContext.Clear();
if (ApplicationContext.AuthenticationType != "Windows")
ApplicationContext.User = null;
}
#endregion
#region Helper methods
private static bool IsTransactionalMethod(MethodInfo method)
{
return Attribute.IsDefined(method, typeof(TransactionalAttribute));
}
private static TransactionalTypes TransactionalType(MethodInfo method)
{
TransactionalTypes result;
if (IsTransactionalMethod(method))
{
TransactionalAttribute attrib =
(TransactionalAttribute)Attribute.GetCustomAttribute(
method, typeof(TransactionalAttribute));
result = attrib.TransactionType;
}
else
result = TransactionalTypes.Manual;
return result;
}
#endregion
}
}

View File

@@ -0,0 +1,88 @@
using System;
using System.Security.Principal;
using System.Threading;
using System.Collections.Specialized;
namespace Csla.Server
{
/// <summary>
/// Provides consistent context information between the client
/// and server DataPortal objects.
/// </summary>
[Serializable()]
public class DataPortalContext
{
private IPrincipal _principal;
private bool _remotePortal;
private string _clientCulture;
private string _clientUICulture;
private HybridDictionary _clientContext;
private HybridDictionary _globalContext;
/// <summary>
/// The current principal object
/// if CSLA security is being used.
/// </summary>
public IPrincipal Principal
{
get { return _principal; }
}
/// <summary>
/// Returns <see langword="true" /> if the
/// server-side DataPortal is running
/// on a remote server via remoting.
/// </summary>
public bool IsRemotePortal
{
get { return _remotePortal; }
}
/// <summary>
/// The culture setting on the client
/// workstation.
/// </summary>
public string ClientCulture
{
get { return _clientCulture; }
}
/// <summary>
/// The culture setting on the client
/// workstation.
/// </summary>
public string ClientUICulture
{
get { return _clientUICulture; }
}
internal HybridDictionary ClientContext
{
get { return _clientContext; }
}
internal HybridDictionary GlobalContext
{
get { return _globalContext; }
}
/// <summary>
/// Creates a new DataPortalContext object.
/// </summary>
/// <param name="principal">The current Principal object.</param>
/// <param name="isRemotePortal">Indicates whether the DataPortal is remote.</param>
public DataPortalContext(IPrincipal principal, bool isRemotePortal)
{
if (isRemotePortal)
{
_principal = principal;
_remotePortal = isRemotePortal;
_clientCulture =
System.Threading.Thread.CurrentThread.CurrentCulture.Name;
_clientUICulture =
System.Threading.Thread.CurrentThread.CurrentUICulture.Name;
_clientContext = Csla.ApplicationContext.GetClientContext();
_globalContext = Csla.ApplicationContext.GetGlobalContext();
}
}
}
}

View File

@@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Csla.Server
{
/// <summary>
/// This exception is returned from the
/// server-side DataPortal and contains the exception
/// and context data from the server.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors")]
[Serializable()]
public class DataPortalException : Exception
{
private DataPortalResult _result;
private string _innerStackTrace;
/// <summary>
/// Returns the DataPortalResult object from the server.
/// </summary>
public DataPortalResult Result
{
get { return _result; }
}
/// <summary>
/// Get the server-side stack trace from the
/// original exception.
/// </summary>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1305:SpecifyIFormatProvider", MessageId = "System.String.Format(System.String,System.Object,System.Object,System.Object)")]
public override string StackTrace
{
get { return String.Format("{0}{1}{2}",
_innerStackTrace, Environment.NewLine, base.StackTrace); }
}
/// <summary>
/// Creates an instance of the object.
/// </summary>
/// <param name="message">Text describing the exception.</param>
/// <param name="ex">Inner exception.</param>
/// <param name="result">The data portal result object.</param>
public DataPortalException(
string message, Exception ex, DataPortalResult result)
: base(message, ex)
{
_innerStackTrace = ex.StackTrace;
_result = result;
}
/// <summary>
/// Creates an instance of the object for serialization.
/// </summary>
/// <param name="info">Serialiation info object.</param>
/// <param name="context">Serialization context object.</param>
protected DataPortalException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
: base(info, context)
{
_result = (DataPortalResult)info.GetValue(
"_result", typeof(DataPortalResult));
_innerStackTrace = info.GetString("_innerStackTrace");
}
/// <summary>
/// Serializes the object.
/// </summary>
/// <param name="info">Serialiation info object.</param>
/// <param name="context">Serialization context object.</param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1062:ValidateArgumentsOfPublicMethods")]
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.LinkDemand, Flags = System.Security.Permissions.SecurityPermissionFlag.SerializationFormatter)]
[System.Security.Permissions.SecurityPermission(System.Security.Permissions.SecurityAction.Demand, Flags = System.Security.Permissions.SecurityPermissionFlag.SerializationFormatter)]
public override void GetObjectData(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
{
base.GetObjectData(info, context);
info.AddValue("_result", _result);
info.AddValue("_innerStackTrace", _innerStackTrace);
}
}
}

View File

@@ -0,0 +1,55 @@
using System;
using System.Collections.Specialized;
using System.Text;
namespace Csla.Server
{
/// <summary>
/// Returns data from the server-side DataPortal to the
/// client-side DataPortal. Intended for internal CSLA .NET
/// use only.
/// </summary>
[Serializable()]
public class DataPortalResult
{
private object _returnObject;
private HybridDictionary _globalContext;
/// <summary>
/// The business object being returned from
/// the server.
/// </summary>
public object ReturnObject
{
get { return _returnObject; }
}
/// <summary>
/// The global context being returned from
/// the server.
/// </summary>
public HybridDictionary GlobalContext
{
get { return _globalContext; }
}
/// <summary>
/// Creates an instance of the object.
/// </summary>
public DataPortalResult()
{
_globalContext = ApplicationContext.GetGlobalContext();
}
/// <summary>
/// Creates an instance of the object.
/// </summary>
/// <param name="returnObject">Object to return as part
/// of the result.</param>
public DataPortalResult(object returnObject)
{
_returnObject = returnObject;
_globalContext = ApplicationContext.GetGlobalContext();
}
}
}

View File

@@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Csla.Server
{
/// <summary>
/// Interface implemented by server-side data portal
/// components.
/// </summary>
public interface IDataPortalServer
{
/// <summary>
/// Create a new business object.
/// </summary>
/// <param name="objectType">Type of business object to create.</param>
/// <param name="criteria">Criteria object describing business object.</param>
/// <param name="context">
/// <see cref="Server.DataPortalContext" /> object passed to the server.
/// </param>
DataPortalResult Create(Type objectType, object criteria, DataPortalContext context);
/// <summary>
/// Get an existing business object.
/// </summary>
/// <param name="objectType">Type of business object to retrieve.</param>
/// <param name="criteria">Criteria object describing business object.</param>
/// <param name="context">
/// <see cref="Server.DataPortalContext" /> object passed to the server.
/// </param>
DataPortalResult Fetch(Type objectType, object criteria, DataPortalContext context);
/// <summary>
/// Update a business object.
/// </summary>
/// <param name="obj">Business object to update.</param>
/// <param name="context">
/// <see cref="Server.DataPortalContext" /> object passed to the server.
/// </param>
DataPortalResult Update(object obj, DataPortalContext context);
/// <summary>
/// Delete a business object.
/// </summary>
/// <param name="criteria">Criteria object describing business object.</param>
/// <param name="context">
/// <see cref="Server.DataPortalContext" /> object passed to the server.
/// </param>
DataPortalResult Delete(object criteria, DataPortalContext context);
}
}

View File

@@ -0,0 +1,97 @@
using System;
using System.EnterpriseServices;
using System.Runtime.InteropServices;
namespace Csla.Server
{
/// <summary>
/// Implements the server-side Serviced
/// DataPortal described in Chapter 4.
/// </summary>
[Transaction(TransactionOption.Required)]
[EventTrackingEnabled(true)]
[ComVisible(true)]
public class ServicedDataPortal : ServicedComponent, IDataPortalServer
{
/// <summary>
/// Wraps a Create call in a ServicedComponent.
/// </summary>
/// <remarks>
/// This method delegates to
/// <see cref="SimpleDataPortal">SimpleDataPortal</see>
/// but wraps that call within a COM+ transaction
/// to provide transactional support.
/// </remarks>
/// <param name="objectType">A <see cref="Type">Type</see> object
/// indicating the type of business object to be created.</param>
/// <param name="criteria">A custom criteria object providing any
/// extra information that may be required to properly create
/// the object.</param>
/// <param name="context">Context data from the client.</param>
/// <returns>A populated business object.</returns>
[AutoComplete(true)]
public DataPortalResult Create(
Type objectType, object criteria, DataPortalContext context)
{
SimpleDataPortal portal = new SimpleDataPortal();
return portal.Create(objectType, criteria, context);
}
/// <summary>
/// Wraps a Fetch call in a ServicedComponent.
/// </summary>
/// <remarks>
/// This method delegates to
/// <see cref="SimpleDataPortal">SimpleDataPortal</see>
/// but wraps that call within a COM+ transaction
/// to provide transactional support.
/// </remarks>
/// <param name="objectType">Type of business object to retrieve.</param>
/// <param name="criteria">Object-specific criteria.</param>
/// <param name="context">Object containing context data from client.</param>
/// <returns>A populated business object.</returns>
[AutoComplete(true)]
public DataPortalResult Fetch(Type objectType, object criteria, DataPortalContext context)
{
SimpleDataPortal portal = new SimpleDataPortal();
return portal.Fetch(objectType, criteria, context);
}
/// <summary>
/// Wraps an Update call in a ServicedComponent.
/// </summary>
/// <remarks>
/// This method delegates to
/// <see cref="SimpleDataPortal">SimpleDataPortal</see>
/// but wraps that call within a COM+ transaction
/// to provide transactional support.
/// </remarks>
/// <param name="obj">A reference to the object being updated.</param>
/// <param name="context">Context data from the client.</param>
/// <returns>A reference to the newly updated object.</returns>
[AutoComplete(true)]
public DataPortalResult Update(object obj, DataPortalContext context)
{
SimpleDataPortal portal = new SimpleDataPortal();
return portal.Update(obj, context);
}
/// <summary>
/// Wraps a Delete call in a ServicedComponent.
/// </summary>
/// <remarks>
/// This method delegates to
/// <see cref="SimpleDataPortal">SimpleDataPortal</see>
/// but wraps that call within a COM+ transaction
/// to provide transactional support.
/// </remarks>
/// <param name="criteria">Object-specific criteria.</param>
/// <param name="context">Context data from the client.</param>
[AutoComplete(true)]
public DataPortalResult Delete(object criteria, DataPortalContext context)
{
SimpleDataPortal portal = new SimpleDataPortal();
return portal.Delete(criteria, context);
}
}
}

View File

@@ -0,0 +1,317 @@
using System;
using System.Reflection;
using System.Security.Principal;
using System.Collections.Specialized;
using Csla.Properties;
namespace Csla.Server
{
/// <summary>
/// Implements the server-side DataPortal as discussed
/// in Chapter 4.
/// </summary>
public class SimpleDataPortal : IDataPortalServer
{
#region Data Access
/// <summary>
/// Create a new business object.
/// </summary>
/// <param name="objectType">Type of business object to create.</param>
/// <param name="criteria">Criteria object describing business object.</param>
/// <param name="context">
/// <see cref="Server.DataPortalContext" /> object passed to the server.
/// </param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "Csla.Server.DataPortalException.#ctor(System.String,System.Exception,Csla.Server.DataPortalResult)")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
public DataPortalResult Create(
Type objectType, object criteria, DataPortalContext context)
{
object obj = null;
try
{
// create an instance of the business object.
obj = Activator.CreateInstance(objectType, true);
// tell the business object we're about to make a DataPortal_xyz call
MethodCaller.CallMethodIfImplemented(
obj, "DataPortal_OnDataPortalInvoke", new DataPortalEventArgs(context));
// tell the business object to create its data
MethodInfo method = MethodCaller.GetCreateMethod(objectType, criteria);
if (criteria is int)
MethodCaller.CallMethod(obj, method);
else
MethodCaller.CallMethod(obj, method, criteria);
// mark the object as new
MethodCaller.CallMethodIfImplemented(
obj, "MarkNew");
// tell the business object the DataPortal_xyz call is complete
MethodCaller.CallMethodIfImplemented(
obj, "DataPortal_OnDataPortalInvokeComplete",
new DataPortalEventArgs(context));
// return the populated business object as a result
return new DataPortalResult(obj);
}
catch (Exception ex)
{
try
{
// tell the business object there was an exception
MethodCaller.CallMethodIfImplemented(
obj, "DataPortal_OnDataPortalException",
new DataPortalEventArgs(context), ex);
}
catch
{
// ignore exceptions from the exception handler
}
throw new DataPortalException(
"DataPortal.Create " + Resources.FailedOnServer,
ex, new DataPortalResult(obj));
}
}
/// <summary>
/// Get an existing business object.
/// </summary>
/// <param name="objectType">Type of business object to retrieve.</param>
/// <param name="criteria">Criteria object describing business object.</param>
/// <param name="context">
/// <see cref="Server.DataPortalContext" /> object passed to the server.
/// </param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "Csla.Server.DataPortalException.#ctor(System.String,System.Exception,Csla.Server.DataPortalResult)")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes")]
public DataPortalResult Fetch(Type objectType, object criteria, DataPortalContext context)
{
object obj = null;
try
{
// create an instance of the business object.
obj = Activator.CreateInstance(objectType, true);
// tell the business object we're about to make a DataPortal_xyz call
MethodCaller.CallMethodIfImplemented(
obj, "DataPortal_OnDataPortalInvoke",
new DataPortalEventArgs(context));
// tell the business object to fetch its data
MethodInfo method = MethodCaller.GetFetchMethod(objectType, criteria);
if (criteria is int)
MethodCaller.CallMethod(obj, method);
else
MethodCaller.CallMethod(obj, method, criteria);
// mark the object as old
MethodCaller.CallMethodIfImplemented(
obj, "MarkOld");
// tell the business object the DataPortal_xyz call is complete
MethodCaller.CallMethodIfImplemented(
obj, "DataPortal_OnDataPortalInvokeComplete",
new DataPortalEventArgs(context));
// return the populated business object as a result
return new DataPortalResult(obj);
}
catch (Exception ex)
{
try
{
// tell the business object there was an exception
MethodCaller.CallMethodIfImplemented(
obj, "DataPortal_OnDataPortalException",
new DataPortalEventArgs(context), ex);
}
catch
{
// ignore exceptions from the exception handler
}
throw new DataPortalException(
"DataPortal.Fetch " + Resources.FailedOnServer,
ex, new DataPortalResult(obj));
}
}
/// <summary>
/// Update a business object.
/// </summary>
/// <param name="obj">Business object to update.</param>
/// <param name="context">
/// <see cref="Server.DataPortalContext" /> object passed to the server.
/// </param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily")]
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "Csla.Server.DataPortalException.#ctor(System.String,System.Exception,Csla.Server.DataPortalResult)")]
public DataPortalResult Update(object obj, DataPortalContext context)
{
try
{
// tell the business object we're about to make a DataPortal_xyz call
MethodCaller.CallMethodIfImplemented(
obj, "DataPortal_OnDataPortalInvoke",
new DataPortalEventArgs(context));
// tell the business object to update itself
if (obj is Core.BusinessBase)
{
Core.BusinessBase busObj = (Core.BusinessBase)obj;
if (busObj.IsDeleted)
{
if (!busObj.IsNew)
{
// tell the object to delete itself
MethodCaller.CallMethod(
busObj, "DataPortal_DeleteSelf");
}
// mark the object as new
MethodCaller.CallMethodIfImplemented(
busObj, "MarkNew");
}
else
{
if (busObj.IsNew)
{
// tell the object to insert itself
MethodCaller.CallMethod(
busObj, "DataPortal_Insert");
}
else
{
// tell the object to update itself
MethodCaller.CallMethod(
busObj, "DataPortal_Update");
}
// mark the object as old
MethodCaller.CallMethodIfImplemented(
busObj, "MarkOld");
}
}
else if (obj is CommandBase)
{
// tell the object to update itself
MethodCaller.CallMethod(
obj, "DataPortal_Execute");
}
else
{
// this is an updatable collection or some other
// non-BusinessBase type of object
// tell the object to update itself
MethodCaller.CallMethod(
obj, "DataPortal_Update");
// mark the object as old
MethodCaller.CallMethodIfImplemented(
obj, "MarkOld");
}
// tell the business object the DataPortal_xyz is complete
MethodCaller.CallMethodIfImplemented(
obj, "DataPortal_OnDataPortalInvokeComplete",
new DataPortalEventArgs(context));
return new DataPortalResult(obj);
}
catch (Exception ex)
{
try
{
// tell the business object there was an exception
MethodCaller.CallMethodIfImplemented(
obj, "DataPortal_OnDataPortalException",
new DataPortalEventArgs(context), ex);
}
catch
{
// ignore exceptions from the exception handler
}
throw new DataPortalException(
"DataPortal.Update " + Resources.FailedOnServer,
ex, new DataPortalResult(obj));
}
}
/// <summary>
/// Delete a business object.
/// </summary>
/// <param name="criteria">Criteria object describing business object.</param>
/// <param name="context">
/// <see cref="Server.DataPortalContext" /> object passed to the server.
/// </param>
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Globalization", "CA1303:DoNotPassLiteralsAsLocalizedParameters", MessageId = "Csla.Server.DataPortalException.#ctor(System.String,System.Exception,Csla.Server.DataPortalResult)")]
public DataPortalResult Delete(object criteria, DataPortalContext context)
{
object obj = null;
try
{
// create an instance of the business objet
obj = CreateBusinessObject(criteria);
// tell the business object we're about to make a DataPortal_xyz call
MethodCaller.CallMethodIfImplemented(
obj, "DataPortal_OnDataPortalInvoke",
new DataPortalEventArgs(context));
// tell the business object to delete itself
MethodCaller.CallMethod(
obj, "DataPortal_Delete", criteria);
// tell the business object the DataPortal_xyz call is complete
MethodCaller.CallMethodIfImplemented(
obj, "DataPortal_OnDataPortalInvokeComplete",
new DataPortalEventArgs(context));
return new DataPortalResult();
}
catch (Exception ex)
{
try
{
// tell the business object there was an exception
MethodCaller.CallMethodIfImplemented(
obj, "DataPortal_OnDataPortalException",
new DataPortalEventArgs(context), ex);
}
catch
{
// ignore exceptions from the exception handler
}
throw new DataPortalException(
"DataPortal.Delete " + Resources.FailedOnServer,
ex, new DataPortalResult());
}
}
#endregion
#region Creating the business object
private static object CreateBusinessObject(object criteria)
{
Type businessType;
if (criteria.GetType().IsSubclassOf(typeof(CriteriaBase)))
{
// get the type of the actual business object
// from CriteriaBase
businessType = ((CriteriaBase)criteria).ObjectType;
}
else
{
// get the type of the actual business object
// based on the nested class scheme in the book
businessType = criteria.GetType().DeclaringType;
}
// create an instance of the business object
return Activator.CreateInstance(businessType, true);
}
#endregion
}
}

View File

@@ -0,0 +1,121 @@
using System;
using System.Transactions;
namespace Csla.Server
{
/// <summary>
/// Implements the server-side Serviced
/// DataPortal described in Chapter 4.
/// </summary>
public class TransactionalDataPortal : IDataPortalServer
{
/// <summary>
/// Wraps a Create call in a TransactionScope
/// </summary>
/// <remarks>
/// This method delegates to
/// <see cref="SimpleDataPortal">SimpleDataPortal</see>
/// but wraps that call within a
/// <see cref="TransactionScope">TransactionScope</see>
/// to provide transactional support via
/// System.Transactions.
/// </remarks>
/// <param name="objectType">A <see cref="Type">Type</see> object
/// indicating the type of business object to be created.</param>
/// <param name="criteria">A custom criteria object providing any
/// extra information that may be required to properly create
/// the object.</param>
/// <param name="context">Context data from the client.</param>
/// <returns>A populated business object.</returns>
public DataPortalResult Create(
System.Type objectType, object criteria, DataPortalContext context)
{
DataPortalResult result;
using (TransactionScope tr = new TransactionScope())
{
SimpleDataPortal portal = new SimpleDataPortal();
result = portal.Create(objectType, criteria, context);
tr.Complete();
}
return result;
}
/// <summary>
/// Called by the client-side DataProtal to retrieve an object.
/// </summary>
/// <remarks>
/// This method delegates to
/// <see cref="SimpleDataPortal">SimpleDataPortal</see>
/// but wraps that call within a
/// <see cref="TransactionScope">TransactionScope</see>
/// to provide transactional support via
/// System.Transactions.
/// </remarks>
/// <param name="objectType">Type of business object to retrieve.</param>
/// <param name="criteria">Object-specific criteria.</param>
/// <param name="context">Object containing context data from client.</param>
/// <returns>A populated business object.</returns>
public DataPortalResult Fetch(Type objectType, object criteria, DataPortalContext context)
{
DataPortalResult result;
using (TransactionScope tr = new TransactionScope())
{
SimpleDataPortal portal = new SimpleDataPortal();
result = portal.Fetch(objectType, criteria, context);
tr.Complete();
}
return result;
}
/// <summary>
/// Called by the client-side DataPortal to update an object.
/// </summary>
/// <remarks>
/// This method delegates to
/// <see cref="SimpleDataPortal">SimpleDataPortal</see>
/// but wraps that call within a
/// <see cref="TransactionScope">TransactionScope</see>
/// to provide transactional support via
/// System.Transactions.
/// </remarks>
/// <param name="obj">A reference to the object being updated.</param>
/// <param name="context">Context data from the client.</param>
/// <returns>A reference to the newly updated object.</returns>
public DataPortalResult Update(object obj, DataPortalContext context)
{
DataPortalResult result;
using (TransactionScope tr = new TransactionScope())
{
SimpleDataPortal portal = new SimpleDataPortal();
result = portal.Update(obj, context);
tr.Complete();
}
return result;
}
/// <summary>
/// Called by the client-side DataPortal to delete an object.
/// </summary>
/// <remarks>
/// This method delegates to
/// <see cref="SimpleDataPortal">SimpleDataPortal</see>
/// but wraps that call within a
/// <see cref="TransactionScope">TransactionScope</see>
/// to provide transactional support via
/// System.Transactions.
/// </remarks>
/// <param name="criteria">Object-specific criteria.</param>
/// <param name="context">Context data from the client.</param>
public DataPortalResult Delete(object criteria, DataPortalContext context)
{
DataPortalResult result;
using (TransactionScope tr = new TransactionScope())
{
SimpleDataPortal portal = new SimpleDataPortal();
result = portal.Delete(criteria, context);
tr.Complete();
}
return result;
}
}
}