Skip to content

Commit

Permalink
Csla.Server namespace nullable aware
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanOssendorf committed Oct 23, 2024
1 parent 2ddb7ff commit 12ac4a0
Show file tree
Hide file tree
Showing 61 changed files with 1,236 additions and 975 deletions.
5 changes: 3 additions & 2 deletions Source/Csla/ApplicationContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ public IContextDictionary ClientContext
{
lock (_syncContext)
{
IContextDictionary ctx = ContextManager.GetClientContext(ExecutionLocation);
IContextDictionary? ctx = ContextManager.GetClientContext(ExecutionLocation);
if (ctx == null)
{
ctx = new ContextDictionary();
Expand All @@ -135,7 +135,7 @@ public IContextDictionary ClientContext
}
}

internal void SetContext(IContextDictionary clientContext)
internal void SetContext(IContextDictionary? clientContext)
{
lock (_syncContext)
ContextManager.SetClientContext(clientContext, ExecutionLocation);
Expand Down Expand Up @@ -449,5 +449,6 @@ internal object CreateGenericInstance(Type type, params Type[] paramTypes)
return CreateInstance(gt);
}

internal void SetUnauthenticatedUser() => ContextManager.SetUser(null);
}
}
2 changes: 1 addition & 1 deletion Source/Csla/Core/IContextManager.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public interface IContextManager
/// Sets the current principal.
/// </summary>
/// <param name="principal">Principal object.</param>
void SetUser(IPrincipal principal);
void SetUser(IPrincipal? principal);
/// <summary>
/// Gets the local context.
/// </summary>
Expand Down
19 changes: 9 additions & 10 deletions Source/Csla/DataPortalClient/DataPortalProxy.cs
Original file line number Diff line number Diff line change
Expand Up @@ -338,15 +338,15 @@ internal bool ExecutionIsNotOnLogicalOrPhysicalServer

private CriteriaRequest GetBaseCriteriaRequest()
{
var result = ApplicationContext.CreateInstanceDI<CriteriaRequest>();
var securityOptions = ApplicationContext.GetRequiredService<SecurityOptions>();
result.CriteriaData = null;
result.ClientContext = ApplicationContext.GetRequiredService<ISerializationFormatter>().Serialize(ApplicationContext.ClientContext);
result.Principal = ApplicationContext.GetRequiredService<ISerializationFormatter>()
.Serialize(securityOptions.FlowSecurityPrincipalFromClient ? ApplicationContext.User : null);
result.ClientCulture = System.Globalization.CultureInfo.CurrentCulture.Name;
result.ClientUICulture = System.Globalization.CultureInfo.CurrentUICulture.Name;
return result;

var serializer = ApplicationContext.GetRequiredService<ISerializationFormatter>();
var clientContext = serializer.Serialize(ApplicationContext.ClientContext);
var principal = serializer.Serialize(securityOptions.FlowSecurityPrincipalFromClient ? ApplicationContext.User : null);
var clientCulture = System.Globalization.CultureInfo.CurrentCulture.Name;
var clientUICulture = System.Globalization.CultureInfo.CurrentUICulture.Name;

return ApplicationContext.CreateInstanceDI<CriteriaRequest>(principal, clientContext, clientCulture, clientUICulture);
}

private UpdateRequest GetBaseUpdateCriteriaRequest()
Expand All @@ -355,8 +355,7 @@ private UpdateRequest GetBaseUpdateCriteriaRequest()
var securityOptions = ApplicationContext.GetRequiredService<SecurityOptions>();
result.ObjectData = null;
result.ClientContext = ApplicationContext.GetRequiredService<ISerializationFormatter>().Serialize(ApplicationContext.ClientContext);
result.Principal = ApplicationContext.GetRequiredService<ISerializationFormatter>()
.Serialize(securityOptions.FlowSecurityPrincipalFromClient ? ApplicationContext.User : null);
result.Principal = ApplicationContext.GetRequiredService<ISerializationFormatter>().Serialize(securityOptions.FlowSecurityPrincipalFromClient ? ApplicationContext.User : null);
result.ClientCulture = Thread.CurrentThread.CurrentCulture.Name;
result.ClientUICulture = Thread.CurrentThread.CurrentUICulture.Name;
return result;
Expand Down
10 changes: 5 additions & 5 deletions Source/Csla/DataPortalEventArgs.cs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ public class DataPortalEventArgs : EventArgs
/// The DataPortalContext object passed to the
/// server-side DataPortal.
/// </summary>
public Server.DataPortalContext DataPortalContext { get; }
public Server.DataPortalContext? DataPortalContext { get; }

/// <summary>
/// Gets the requested data portal operation.
Expand All @@ -34,7 +34,7 @@ public class DataPortalEventArgs : EventArgs
/// exception occurred. Exceptions are returned only as part
/// of a data portal complete event or method.
/// </remarks>
public Exception Exception { get; }
public Exception? Exception { get; }

/// <summary>
/// Gets the object type being processed by the
Expand All @@ -46,7 +46,7 @@ public class DataPortalEventArgs : EventArgs
/// Gets the criteria object or business object
/// being processed by the data portal.
/// </summary>
public object Object { get; }
public object? Object { get; }

/// <summary>
/// Creates an instance of the type.
Expand All @@ -63,7 +63,7 @@ public class DataPortalEventArgs : EventArgs
/// <param name="operation">
/// Data portal operation being performed.
/// </param>
public DataPortalEventArgs(Server.DataPortalContext dataPortalContext, Type objectType, object obj, DataPortalOperations operation)
public DataPortalEventArgs(Server.DataPortalContext? dataPortalContext, Type objectType, object? obj, DataPortalOperations operation)
{
DataPortalContext = dataPortalContext;
Operation = operation;
Expand All @@ -89,7 +89,7 @@ public DataPortalEventArgs(Server.DataPortalContext dataPortalContext, Type obje
/// <param name="exception">
/// Exception encountered during processing.
/// </param>
public DataPortalEventArgs(Server.DataPortalContext dataPortalContext, Type objectType, object obj, DataPortalOperations operation, Exception exception)
public DataPortalEventArgs(Server.DataPortalContext dataPortalContext, Type objectType, object? obj, DataPortalOperations operation, Exception exception)
: this(dataPortalContext, objectType, obj, operation)
{
Exception = exception;
Expand Down
4 changes: 2 additions & 2 deletions Source/Csla/DataPortalException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public DataPortalException(string message, object businessObject)
/// <param name="ex">Inner exception.</param>
/// <param name="businessObject">The business object
/// as it was at the time of the exception.</param>
public DataPortalException(string message, Exception ex, object businessObject)
public DataPortalException(string message, Exception ex, object? businessObject)
: base(message, ex)
{
_innerStackTrace = ex.StackTrace;
Expand Down Expand Up @@ -132,7 +132,7 @@ public DataPortalErrorInfo BusinessErrorInfo
/// state may have been altered by the server and
/// may no longer reflect data in the database.
/// </remarks>
public object BusinessObject { get; }
public object? BusinessObject { get; }

private Exception _businessException;

Expand Down
119 changes: 53 additions & 66 deletions Source/Csla/DataPortalT.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,12 @@
// <summary>Client side data portal used for making asynchronous</summary>
//-----------------------------------------------------------------------

using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using Csla.Configuration;
using Csla.DataPortalClient;
using Csla.Properties;
using Csla.Reflection;

namespace Csla
{
Expand Down Expand Up @@ -90,7 +92,7 @@ private Reflection.ServiceProviderMethodCaller ServiceProviderMethodCaller
get
{
if (serviceProviderMethodCaller == null)
serviceProviderMethodCaller = (Reflection.ServiceProviderMethodCaller)_applicationContext.CreateInstanceDI(typeof(Reflection.ServiceProviderMethodCaller));
serviceProviderMethodCaller = _applicationContext.CreateInstanceDI< ServiceProviderMethodCaller>();
return serviceProviderMethodCaller;
}
}
Expand All @@ -102,19 +104,12 @@ private async Task<object> DoCreateAsync(Type objectType, object criteria, bool
try
{
if (!await Csla.Rules.BusinessRules.HasPermissionAsync(_applicationContext, Rules.AuthorizationActions.CreateObject, objectType, Server.DataPortal.GetCriteriaArray(criteria), ct))
throw new Csla.Security.SecurityException(string.Format(
Resources.UserNotAuthorizedException,
"create",
objectType.Name));
Reflection.ServiceProviderMethodInfo method;
if (criteria is Server.EmptyCriteria)
method = ServiceProviderMethodCaller.FindDataPortalMethod<CreateAttribute>(objectType, null, false);
else
method = ServiceProviderMethodCaller.FindDataPortalMethod<CreateAttribute>(objectType, Server.DataPortal.GetCriteriaArray(criteria), false);
throw new Csla.Security.SecurityException(string.Format(Resources.UserNotAuthorizedException, "create", objectType.Name));

_ = ServiceProviderMethodCaller.TryGetProviderMethodInfoFor<CreateAttribute>(objectType, criteria, out var method);
var proxy = GetDataPortalProxy(method);

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

try
{
Expand Down Expand Up @@ -201,20 +196,17 @@ private async Task<object> DoFetchAsync(Type objectType, object criteria, bool i

Server.DataPortalResult result = null;
Server.DataPortalContext dpContext = null;
Reflection.ServiceProviderMethodInfo method = null;
Reflection.ServiceProviderMethodInfo? method = null;
try
{
if (!await Csla.Rules.BusinessRules.HasPermissionAsync(_applicationContext, Rules.AuthorizationActions.GetObject, objectType, Server.DataPortal.GetCriteriaArray(criteria), ct))
throw new Csla.Security.SecurityException(string.Format(
Resources.UserNotAuthorizedException,
"get",
objectType.Name));
method = ServiceProviderMethodCaller.FindDataPortalMethod<FetchAttribute>(objectType, Server.DataPortal.GetCriteriaArray(criteria), false);
throw new Csla.Security.SecurityException(string.Format(Resources.UserNotAuthorizedException, "get", objectType.Name));

_ = ServiceProviderMethodCaller.TryGetProviderMethodInfoFor<FetchAttribute>(objectType, criteria, out method);

var proxy = GetDataPortalProxy(method);

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

try
{
Expand Down Expand Up @@ -244,45 +236,39 @@ private async Task<object> DoFetchAsync(Type objectType, object criteria, bool i

private async Task<object> DoExecuteAsync(Type objectType, object criteria, bool isSync, CancellationToken ct = default)
{
Server.DataPortalResult result = null;
Server.DataPortalContext dpContext = null;
Reflection.ServiceProviderMethodInfo method = null;
try
{
if (!await Csla.Rules.BusinessRules.HasPermissionAsync(_applicationContext, Rules.AuthorizationActions.EditObject, objectType, Server.DataPortal.GetCriteriaArray(criteria), ct))
throw new Csla.Security.SecurityException(string.Format(Resources.UserNotAuthorizedException,
"execute",
objectType.Name));
method = ServiceProviderMethodCaller.FindDataPortalMethod<ExecuteAttribute>(objectType, Server.DataPortal.GetCriteriaArray(criteria), false);
Server.DataPortalResult? result = null;
Server.DataPortalContext? dpContext = null;
Reflection.ServiceProviderMethodInfo? method = null;

var proxy = GetDataPortalProxy(method);
if (!await Csla.Rules.BusinessRules.HasPermissionAsync(_applicationContext, Rules.AuthorizationActions.EditObject, objectType, Server.DataPortal.GetCriteriaArray(criteria), ct))
throw new Csla.Security.SecurityException(string.Format(Resources.UserNotAuthorizedException,
"execute",
objectType.Name));

dpContext =
new Server.DataPortalContext(_applicationContext, proxy.IsServerRemote);
_ = ServiceProviderMethodCaller.TryGetProviderMethodInfoFor<ExecuteAttribute>(objectType, criteria, out method);
var proxy = GetDataPortalProxy(method);

try
{
result = await Cache.GetDataPortalResultAsync(objectType, criteria, DataPortalOperations.Execute,
async () => await proxy.Fetch(objectType, criteria, dpContext, isSync));
}
catch (AggregateException ex)
{
if (ex.InnerExceptions.Count > 0)
{
if (ex.InnerExceptions[0] is Server.DataPortalException dpe)
HandleDataPortalException("Execute", dpe);
}
throw new DataPortalException($"DataPortal.Execute {Resources.Failed}", ex, null);
}
catch (Server.DataPortalException ex)
dpContext = new Server.DataPortalContext(_applicationContext, proxy.IsServerRemote);

try
{
result = await Cache.GetDataPortalResultAsync(objectType, criteria, DataPortalOperations.Execute,
async () => await proxy.Fetch(objectType, criteria, dpContext, isSync));
}
catch (AggregateException ex)
{
if (ex.InnerExceptions.Count > 0)
{
HandleDataPortalException("Execute", ex);
if (ex.InnerExceptions[0] is Server.DataPortalException dpe)
HandleDataPortalException("Execute", dpe);
}
throw new DataPortalException($"DataPortal.Execute {Resources.Failed}", ex, null);
}
catch
catch (Server.DataPortalException ex)
{
throw;
HandleDataPortalException("Execute", ex);
}

return result.ReturnObject;
}

Expand Down Expand Up @@ -347,7 +333,7 @@ internal async Task<T> DoUpdateAsync(T obj, bool isSync, CancellationToken ct =
var factoryInfo = Server.ObjectFactoryAttribute.GetObjectFactoryAttribute(objectType);
if (factoryInfo != null)
{
Server.DataPortalMethodInfo method = null;
Server.DataPortalMethodInfo? method = null;
var factoryLoader = _applicationContext.CurrentServiceProvider.GetService(typeof(Server.IObjectFactoryLoader)) as Server.IObjectFactoryLoader;
var factoryType = factoryLoader?.GetFactoryType(factoryInfo.FactoryTypeName);

Expand Down Expand Up @@ -405,13 +391,13 @@ internal async Task<T> DoUpdateAsync(T obj, bool isSync, CancellationToken ct =
method = Server.DataPortalMethodCache.GetMethodInfo(factoryType, factoryInfo.UpdateMethodName, [obj]);
}
}
if (method == null)
method = new Server.DataPortalMethodInfo();
proxy = GetDataPortalProxy(method.RunLocal);

var runLocal = method?.RunLocal ?? false;
proxy = GetDataPortalProxy(runLocal);
}
else
{
Reflection.ServiceProviderMethodInfo method;
Reflection.ServiceProviderMethodInfo? method;
var criteria = Server.DataPortal.GetCriteriaArray(Server.EmptyCriteria.Instance);
if (obj is Core.ICommandObject)
{
Expand All @@ -420,7 +406,7 @@ internal async Task<T> DoUpdateAsync(T obj, bool isSync, CancellationToken ct =
throw new Csla.Security.SecurityException(string.Format(Resources.UserNotAuthorizedException,
"execute",
objectType.Name));
method = ServiceProviderMethodCaller.FindDataPortalMethod<ExecuteAttribute>(objectType, criteria, false);
_ = ServiceProviderMethodCaller.TryFindDataPortalMethod<ExecuteAttribute>(objectType, criteria, out method);
}
else
{
Expand All @@ -432,28 +418,28 @@ internal async Task<T> DoUpdateAsync(T obj, bool isSync, CancellationToken ct =
throw new Csla.Security.SecurityException(string.Format(Resources.UserNotAuthorizedException,
"delete",
objectType.Name));
method = ServiceProviderMethodCaller.FindDataPortalMethod<DeleteSelfAttribute>(objectType, criteria, false);
_ = ServiceProviderMethodCaller.TryFindDataPortalMethod<DeleteSelfAttribute>(objectType, criteria, out method);
}
else if (bbase.IsNew)
{
if (!await Csla.Rules.BusinessRules.HasPermissionAsync(_applicationContext, Rules.AuthorizationActions.CreateObject, obj, ct))
throw new Csla.Security.SecurityException(string.Format(Resources.UserNotAuthorizedException,
"create",
objectType.Name));
method = ServiceProviderMethodCaller.FindDataPortalMethod<InsertAttribute>(objectType, criteria, false);
_ = ServiceProviderMethodCaller.TryFindDataPortalMethod<InsertAttribute>(objectType, criteria, out method);
}
else
{
if (!await Csla.Rules.BusinessRules.HasPermissionAsync(_applicationContext, Rules.AuthorizationActions.EditObject, obj, ct))
throw new Csla.Security.SecurityException(string.Format(Resources.UserNotAuthorizedException,
"save",
objectType.Name));
method = ServiceProviderMethodCaller.FindDataPortalMethod<UpdateAttribute>(objectType, criteria, false);
_ = ServiceProviderMethodCaller.TryFindDataPortalMethod<UpdateAttribute>(objectType, criteria, out method);
}
}
else
{
method = ServiceProviderMethodCaller.FindDataPortalMethod<UpdateAttribute>(objectType, criteria, false);
_ = ServiceProviderMethodCaller.TryFindDataPortalMethod<UpdateAttribute>(objectType, criteria, out method);
}
}
proxy = GetDataPortalProxy(method);
Expand Down Expand Up @@ -500,15 +486,16 @@ private void HandleUpdateDataPortalException(Server.DataPortalException ex)
HandleDataPortalException("Update", ex);
}

#if NET8_0_OR_GREATER
[DoesNotReturn]
#endif
private void HandleDataPortalException(string operation, Server.DataPortalException ex)
{
var result = ex.Result;
var original = ex.InnerException;
if (original.InnerException != null)
original = original.InnerException;
throw new DataPortalException(
String.Format("DataPortal.{2} {0} ({1})", Resources.Failed, original.Message, operation),
ex.InnerException, result.ReturnObject);
throw new DataPortalException(String.Format("DataPortal.{2} {0} ({1})", Resources.Failed, original.Message, operation), ex.InnerException, result.ReturnObject);
}

/// <summary>
Expand Down Expand Up @@ -552,7 +539,7 @@ internal async Task DoDeleteAsync(Type objectType, object criteria, bool isSync,
"delete",
objectType.Name));

var method = ServiceProviderMethodCaller.FindDataPortalMethod<DeleteAttribute>(objectType, Server.DataPortal.GetCriteriaArray(criteria), false);
_ = ServiceProviderMethodCaller.TryGetProviderMethodInfoFor<DeleteAttribute>(objectType, criteria, out var method);
var proxy = GetDataPortalProxy(method);

dpContext = new Server.DataPortalContext(_applicationContext, proxy.IsServerRemote);
Expand Down Expand Up @@ -676,7 +663,7 @@ public async Task<T> ExecuteAsync(params object[] criteria)
return (T)await DoFetchAsync(typeof(T), Server.DataPortal.GetCriteriaFromArray(criteria), false);
}

private IDataPortalProxy GetDataPortalProxy(Reflection.ServiceProviderMethodInfo method)
private IDataPortalProxy GetDataPortalProxy(Reflection.ServiceProviderMethodInfo? method)
{
if (method != null)
return GetDataPortalProxy(method.MethodInfo.RunLocal());
Expand Down
9 changes: 9 additions & 0 deletions Source/Csla/Properties/Resources.Designer.cs

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 12ac4a0

Please sign in to comment.