Commit for development environment setup
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
@@ -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
|
||||
|
||||
}
|
||||
}
|
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user