Skip to content

Commit ceb23c1

Browse files
Add NRT to Csla-Core library (#4528)
* Nullability for Csla.Configuration.* namespace added #1233 * Csla.Core.FieldManager namespace nullable aware #1233 * Csla.Core.LoadManager namespace nullable aware #1233 * Csla.Core.TypeConverters namespace nullable aware #1233 * Csla.Core nullability added till file IUseFieldManager.cs (still WIP) #1233 * Csla.Core namespace nullable aware (finished) #1233 * Csla.Data namespace nullable aware #1233 * Csla.DataPortalClient namespace nullable aware #1233 * Csla.Reflection namespace nullable aware #1233 * Csla.Rules namspace nullable aware #1233 * Csla.Runtime namespace nullable aware #1233 * Csla.Security namespace nullable aware (except types which may be dead) * Csla.Serialization namespace nullable aware (work in progress) #1233 * NRT errors fixed * Add breaking change log for CslaModelBinder * Csla.Serialization namespace nullable aware (finished) * Nullable errors fixed in already migrated projects Fixes #1233 * Csla.Server namespace nullable aware * Nullable errors fixed in already migrated projects Fixes #1233 * Fixes error of main merge * Csla.State namespace nullable aware Fixes #1233 * Unnecessary #nullabe enables removed * Csla.Threading nullable aware Fixes #1233 * Csla nullable aware Csla nullable aware (WIP) Also fixing affected places Fixes #1233 * NRT errors fixed * Make IContextManager.SetUser IPrincipal non nullable * Fixing broken tests due to NRT addition * DataPortalResponse changed to MobileObject as base class * More tests fixed NRT annotations adjusted as necessary * Streamline DynamicMemberHandle usage * #if NET8 removed * More fixes * Fix last broken tests * #if NET8 removed where possible * Fix tests * Add missing AOT annotations
1 parent d74a57b commit ceb23c1

File tree

326 files changed

+8922
-7577
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

326 files changed

+8922
-7577
lines changed

Source/Csla.AspNetCore/Blazor/ApplicationContextManagerBlazor.cs

+1-4
Original file line numberDiff line numberDiff line change
@@ -130,10 +130,7 @@ public IPrincipal GetUser()
130130
return CurrentPrincipal;
131131
}
132132

133-
/// <summary>
134-
/// Not supported in Blazor.
135-
/// </summary>
136-
/// <param name="principal">Principal object.</param>
133+
/// <inheritdoc />
137134
public virtual void SetUser(IPrincipal principal)
138135
{
139136
ArgumentNullException.ThrowIfNull(principal);

Source/Csla.AspNetCore/Blazor/ApplicationContextManagerInMemory.cs

+8-6
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,11 @@ public IPrincipal GetUser()
129129
return CurrentPrincipal;
130130
}
131131

132-
/// <summary>
133-
/// Attempts to set the current principal on the registered
134-
/// IHostEnvironmentAuthenticationStateProvider service.
135-
/// </summary>
136-
/// <param name="principal">Principal object.</param>
132+
/// <inheritdoc />
137133
public virtual void SetUser(IPrincipal principal)
138134
{
135+
ArgumentNullException.ThrowIfNull(principal);
136+
139137
if (!ReferenceEquals(CurrentPrincipal, principal))
140138
{
141139
if (ActiveCircuitState.CircuitExists)
@@ -151,7 +149,11 @@ public virtual void SetUser(IPrincipal principal)
151149
}
152150
else if (HttpContext is not null)
153151
{
154-
HttpContext.User = (ClaimsPrincipal)principal;
152+
if (principal is not ClaimsPrincipal claimsPrincipal)
153+
{
154+
throw new ArgumentException("typeof(principal) != ClaimsPrincipal");
155+
}
156+
HttpContext.User = claimsPrincipal;
155157
}
156158
else
157159
{

Source/Csla.AspNetCore/Blazor/State/StateController.cs

+8-3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
using Csla.Security;
1212
using Csla.Blazor.State.Messages;
1313
using Csla.Serialization;
14+
using System.Runtime.Serialization;
15+
using Csla.Properties;
1416

1517
namespace Csla.AspNetCore.Blazor.State
1618
{
@@ -45,8 +47,7 @@ public virtual StateResult Get(long lastTouched)
4547
}
4648
else
4749
{
48-
var message = (SessionMessage)applicationContext.CreateInstanceDI(typeof(SessionMessage));
49-
message.Session = session;
50+
var message = applicationContext.CreateInstanceDI<SessionMessage>(session);
5051
if (FlowUserIdentityToWebAssembly)
5152
{
5253
message.Principal = applicationContext.Principal;
@@ -73,7 +74,11 @@ public virtual void Put(byte[] updatedSessionData)
7374
{
7475
Position = 0
7576
};
76-
var session = (Session)formatter.Deserialize(buffer);
77+
if (formatter.Deserialize(buffer) is not Session session)
78+
{
79+
throw new SerializationException(string.Format(Resources.DeserializationFailedDueToWrongData, nameof(Session)));
80+
}
81+
7782
sessionManager.UpdateSession(session);
7883
}
7984
}

Source/Csla.AspNetCore/ConfigurationExtensions.cs

+4
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using Microsoft.Extensions.DependencyInjection;
1414
using Csla.Core;
1515
using Csla.AspNetCore;
16+
using Csla.Web.Mvc;
1617

1718
namespace Csla.Configuration
1819
{
@@ -45,6 +46,9 @@ public static CslaOptions AddAspNetCore(this CslaOptions config, Action<AspNetCo
4546
#if NET8_0_OR_GREATER
4647
config.Services.AddScoped<ActiveCircuitState>();
4748
config.Services.AddScoped(typeof(CircuitHandler), typeof(ActiveCircuitHandler));
49+
#endif
50+
#if NETSTANDARD2_0 || NET8_0_OR_GREATER
51+
config.Services.AddMvcCore(opt => opt.ModelBinderProviders.Insert(0, new CslaModelBinderProvider()));
4852
#endif
4953
config.Services.AddScoped(typeof(IContextManager), typeof(ApplicationContextManagerHttpContext));
5054
return config;

Source/Csla.AspNetCore/Mvc/TagHelpers/CslaErrorsTagHelper.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// </copyright>
66
// <summary>Razor tag helper</summary>
77
//-----------------------------------------------------------------------
8+
using Csla.Properties;
89
using Csla.Rules;
910
using Microsoft.AspNetCore.Mvc.ViewFeatures;
1011
using Microsoft.AspNetCore.Razor.TagHelpers;
@@ -39,7 +40,7 @@ public override void Process(TagHelperContext context, TagHelperOutput output)
3940
var propertyName = parts[parts.Length - 1];
4041
object source = model;
4142
for (int i = 0; i < parts.Length - 1; i++)
42-
source = Reflection.MethodCaller.CallPropertyGetter(source, parts[i]);
43+
source = Reflection.MethodCaller.CallPropertyGetter(source, parts[i]) ?? throw new InvalidOperationException(string.Format(Resources.TagHelperPropertyInPathHasNullValue, parts[i], CslaErrorsFor.Name));
4344
var result = string.Empty;
4445
if (source is Core.BusinessBase obj)
4546
result = obj.BrokenRulesCollection.ToString(",", RuleSeverity.Error, propertyName);

Source/Csla.AspNetCore/Mvc/TagHelpers/CslaInformationTagHelper.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// </copyright>
66
// <summary>Razor tag helper</summary>
77
//-----------------------------------------------------------------------
8+
using Csla.Properties;
89
using Csla.Rules;
910
using Microsoft.AspNetCore.Mvc.ViewFeatures;
1011
using Microsoft.AspNetCore.Razor.TagHelpers;
@@ -39,7 +40,7 @@ public override void Process(TagHelperContext context, TagHelperOutput output)
3940
var propertyName = parts[parts.Length - 1];
4041
object source = model;
4142
for (int i = 0; i < parts.Length - 1; i++)
42-
source = Reflection.MethodCaller.CallPropertyGetter(source, parts[i]);
43+
source = Reflection.MethodCaller.CallPropertyGetter(source, parts[i]) ?? throw new InvalidOperationException(string.Format(Resources.TagHelperPropertyInPathHasNullValue, parts[i], CslaInformationFor.Name));
4344
var result = string.Empty;
4445
if (source is Core.BusinessBase obj)
4546
result = obj.BrokenRulesCollection.ToString(",", RuleSeverity.Information, propertyName);

Source/Csla.AspNetCore/Mvc/TagHelpers/CslaWarningsTagHelper.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
// </copyright>
66
// <summary>Razor tag helper</summary>
77
//-----------------------------------------------------------------------
8+
using Csla.Properties;
89
using Csla.Rules;
910
using Microsoft.AspNetCore.Mvc.ViewFeatures;
1011
using Microsoft.AspNetCore.Razor.TagHelpers;
@@ -39,7 +40,7 @@ public override void Process(TagHelperContext context, TagHelperOutput output)
3940
var propertyName = parts[parts.Length - 1];
4041
object source = model;
4142
for (int i = 0; i < parts.Length - 1; i++)
42-
source = Reflection.MethodCaller.CallPropertyGetter(source, parts[i]);
43+
source = Reflection.MethodCaller.CallPropertyGetter(source, parts[i]) ?? throw new InvalidOperationException(string.Format(Resources.TagHelperPropertyInPathHasNullValue, parts[i], CslaWarningsFor.Name));
4344
var result = string.Empty;
4445
if (source is Core.BusinessBase obj)
4546
result = obj.BrokenRulesCollection.ToString(",", RuleSeverity.Warning, propertyName);

Source/Csla.Blazor.WebAssembly.Tests/SessionManagerTests.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,9 @@ public void Initialize()
3232
var provider = services.BuildServiceProvider();
3333
var _applicationContext = provider.GetRequiredService<ApplicationContext>();
3434

35-
_sessionValue = new SessionMessage
35+
_sessionValue = new SessionMessage([])
3636
{
37-
Principal = new ClaimsPrincipal() { },
38-
Session = []
37+
Principal = new ClaimsPrincipal()
3938
};
4039

4140
_sessionManager = new SessionManager(_applicationContext, GetHttpClient(_sessionValue, _applicationContext), new BlazorWebAssemblyConfigurationOptions { SyncContextWithServer = true });

Source/Csla.Channels.Grpc/Csla.Channels.Grpc.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk">
1+
<Project Sdk="Microsoft.NET.Sdk">
22
<Import Project="..\Directory.Package.props" />
33

44
<PropertyGroup>

Source/Csla.Channels.Grpc/GrpcPortal.cs

+41-33
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
// <summary>Exposes server-side DataPortal functionality</summary>
77
//-----------------------------------------------------------------------
88

9+
using System.Runtime.Serialization;
910
using System.Security.Principal;
1011
using Csla.Core;
12+
using Csla.Properties;
1113
using Csla.Serialization;
1214
using Csla.Serialization.Mobile;
1315
using Csla.Server;
@@ -109,21 +111,19 @@ protected virtual async Task<ResponseMessage> RouteMessage(string operation, str
109111

110112
private async Task<ResponseMessage> InvokePortal(string operation, ByteString requestData)
111113
{
112-
var result = _applicationContext.CreateInstanceDI<DataPortalResponse>();
113-
DataPortalErrorInfo? errorData = null;
114+
var result = new DataPortalResponse();
114115
try
115116
{
116-
var request = _applicationContext.GetRequiredService<ISerializationFormatter>().Deserialize(requestData.ToByteArray());
117-
result = await CallPortal(operation, request);
117+
var request = Deserialize<object>(requestData.ToByteArray());
118+
var callResult = await CallPortal(operation, request);
119+
result.ObjectData = callResult.ObjectData;
118120
}
119121
catch (Exception ex)
120122
{
121-
errorData = _applicationContext.CreateInstanceDI<DataPortalErrorInfo>(ex);
123+
result.ErrorData = _applicationContext.CreateInstanceDI<DataPortalErrorInfo>(ex);
122124
}
123-
var portalResult = _applicationContext.CreateInstanceDI<DataPortalResponse>();
124-
portalResult.ErrorData = errorData;
125-
portalResult.ObjectData = result.ObjectData;
126-
var buffer = _applicationContext.GetRequiredService<ISerializationFormatter>().Serialize(portalResult);
125+
126+
var buffer = _applicationContext.GetRequiredService<ISerializationFormatter>().Serialize(result);
127127
return new ResponseMessage { Body = ByteString.CopyFrom(buffer) };
128128
}
129129

@@ -149,25 +149,25 @@ public async Task<DataPortalResponse> Create(CriteriaRequest request)
149149
if (request is null)
150150
throw new ArgumentNullException(nameof(request));
151151

152-
var result = _applicationContext.CreateInstanceDI<DataPortalResponse>();
152+
var result = new DataPortalResponse();
153153
try
154154
{
155155
request = ConvertRequest(request);
156156

157157
// unpack criteria data into object
158-
object? criteria = GetCriteria(_applicationContext, request.CriteriaData);
158+
object criteria = GetCriteria(_applicationContext, request.CriteriaData);
159159
if (criteria is DataPortalClient.PrimitiveCriteria primitiveCriteria)
160160
{
161161
criteria = primitiveCriteria.Value;
162162
}
163163

164-
var objectType = Reflection.MethodCaller.GetType(AssemblyNameTranslator.GetAssemblyQualifiedName(request.TypeName), true);
164+
var objectType = Reflection.MethodCaller.GetType(AssemblyNameTranslator.GetAssemblyQualifiedName(request.TypeName));
165165
var context = new DataPortalContext(
166-
_applicationContext, (IPrincipal)_applicationContext.GetRequiredService<ISerializationFormatter>().Deserialize(request.Principal),
166+
_applicationContext, Deserialize<IPrincipal>(request.Principal),
167167
true,
168168
request.ClientCulture,
169169
request.ClientUICulture,
170-
(IContextDictionary)_applicationContext.GetRequiredService<ISerializationFormatter>().Deserialize(request.ClientContext));
170+
Deserialize<IContextDictionary>(request.ClientContext));
171171

172172
var dpr = await dataPortalServer.Create(objectType, criteria, context, true);
173173

@@ -197,25 +197,25 @@ public async Task<DataPortalResponse> Fetch(CriteriaRequest request)
197197
if (request is null)
198198
throw new ArgumentNullException(nameof(request));
199199

200-
var result = _applicationContext.CreateInstanceDI<DataPortalResponse>();
200+
var result = new DataPortalResponse();
201201
try
202202
{
203203
request = ConvertRequest(request);
204204

205205
// unpack criteria data into object
206-
object? criteria = GetCriteria(_applicationContext, request.CriteriaData);
206+
object criteria = GetCriteria(_applicationContext, request.CriteriaData);
207207
if (criteria is DataPortalClient.PrimitiveCriteria primitiveCriteria)
208208
{
209209
criteria = primitiveCriteria.Value;
210210
}
211211

212-
var objectType = Reflection.MethodCaller.GetType(AssemblyNameTranslator.GetAssemblyQualifiedName(request.TypeName), true);
212+
var objectType = Reflection.MethodCaller.GetType(AssemblyNameTranslator.GetAssemblyQualifiedName(request.TypeName));
213213
var context = new DataPortalContext(
214-
_applicationContext, (IPrincipal)_applicationContext.GetRequiredService<ISerializationFormatter>().Deserialize(request.Principal),
214+
_applicationContext, Deserialize<IPrincipal>(request.Principal),
215215
true,
216216
request.ClientCulture,
217217
request.ClientUICulture,
218-
(IContextDictionary)_applicationContext.GetRequiredService<ISerializationFormatter>().Deserialize(request.ClientContext));
218+
Deserialize<IContextDictionary>(request.ClientContext));
219219

220220
var dpr = await dataPortalServer.Fetch(objectType, criteria, context, true);
221221

@@ -245,19 +245,19 @@ public async Task<DataPortalResponse> Update(UpdateRequest request)
245245
if (request is null)
246246
throw new ArgumentNullException(nameof(request));
247247

248-
var result = _applicationContext.CreateInstanceDI<DataPortalResponse>();
248+
var result = new DataPortalResponse();
249249
try
250250
{
251251
request = ConvertRequest(request);
252252
// unpack object
253-
object? obj = GetCriteria(_applicationContext, request.ObjectData);
253+
object obj = GetCriteria(_applicationContext, request.ObjectData) ?? throw new InvalidOperationException(Resources.ObjectToBeUpdatedCouldNotBeDeserialized);
254254

255255
var context = new DataPortalContext(
256-
_applicationContext, (IPrincipal)_applicationContext.GetRequiredService<ISerializationFormatter>().Deserialize(request.Principal),
256+
_applicationContext, Deserialize<IPrincipal>(request.Principal),
257257
true,
258258
request.ClientCulture,
259259
request.ClientUICulture,
260-
(IContextDictionary)_applicationContext.GetRequiredService<ISerializationFormatter>().Deserialize(request.ClientContext));
260+
Deserialize<IContextDictionary>(request.ClientContext));
261261

262262
var dpr = await dataPortalServer.Update(obj, context, true);
263263

@@ -288,25 +288,25 @@ public async Task<DataPortalResponse> Delete(CriteriaRequest request)
288288
if (request is null)
289289
throw new ArgumentNullException(nameof(request));
290290

291-
var result = _applicationContext.CreateInstanceDI<DataPortalResponse>();
291+
var result = new DataPortalResponse();
292292
try
293293
{
294294
request = ConvertRequest(request);
295295

296296
// unpack criteria data into object
297-
object? criteria = GetCriteria(_applicationContext, request.CriteriaData);
297+
object criteria = GetCriteria(_applicationContext, request.CriteriaData);
298298
if (criteria is DataPortalClient.PrimitiveCriteria primitiveCriteria)
299299
{
300300
criteria = primitiveCriteria.Value;
301301
}
302302

303-
var objectType = Reflection.MethodCaller.GetType(AssemblyNameTranslator.GetAssemblyQualifiedName(request.TypeName), true);
303+
var objectType = Reflection.MethodCaller.GetType(AssemblyNameTranslator.GetAssemblyQualifiedName(request.TypeName));
304304
var context = new DataPortalContext(
305-
_applicationContext, (IPrincipal)_applicationContext.GetRequiredService<ISerializationFormatter>().Deserialize(request.Principal),
305+
_applicationContext, Deserialize<IPrincipal>(request.Principal),
306306
true,
307307
request.ClientCulture,
308308
request.ClientUICulture,
309-
(IContextDictionary)_applicationContext.GetRequiredService<ISerializationFormatter>().Deserialize(request.ClientContext));
309+
Deserialize<IContextDictionary>(request.ClientContext));
310310

311311
var dpr = await dataPortalServer.Delete(objectType, criteria, context, true);
312312

@@ -328,12 +328,9 @@ public async Task<DataPortalResponse> Delete(CriteriaRequest request)
328328

329329
#region Criteria
330330

331-
private static object? GetCriteria(ApplicationContext applicationContext, byte[]? criteriaData)
331+
private static object GetCriteria(ApplicationContext applicationContext, byte[] criteriaData)
332332
{
333-
object? criteria = null;
334-
if (criteriaData != null)
335-
criteria = applicationContext.GetRequiredService<ISerializationFormatter>().Deserialize(criteriaData);
336-
return criteria;
333+
return applicationContext.GetRequiredService<ISerializationFormatter>().Deserialize(criteriaData) ?? throw new SerializationException(Resources.ServerSideDataPortalRequestDeserializationFailed);
337334
}
338335

339336
#endregion Criteria
@@ -371,5 +368,16 @@ protected virtual DataPortalResponse ConvertResponse(DataPortalResponse response
371368
}
372369

373370
#endregion Extention Method for Requests
371+
372+
private T Deserialize<T>(byte[] data)
373+
{
374+
var deserializedData = _applicationContext.GetRequiredService<ISerializationFormatter>().Deserialize(data) ?? throw new SerializationException(Resources.ServerSideDataPortalRequestDeserializationFailed);
375+
if (deserializedData is not T castedData)
376+
{
377+
throw new SerializationException(string.Format(Resources.DeserializationFailedDueToWrongData, typeof(T).FullName));
378+
}
379+
380+
return castedData;
381+
}
374382
}
375383
}

Source/Csla.Channels.Grpc/GrpcProxy.cs

+5-2
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ public GrpcProxy(ApplicationContext applicationContext, GrpcChannel channel, Grp
4646
private static GrpcChannel? _defaultChannel;
4747
private string? _versionRoutingTag;
4848

49+
/// <inheritdoc />
50+
public override string DataPortalUrl { get; }
51+
4952
/// <summary>
5053
/// Gets the GrpcChannel used by the gRPC client.
5154
/// </summary>
@@ -91,7 +94,7 @@ protected virtual GrpcService.GrpcServiceClient GetGrpcClient()
9194
/// <param name="routingToken">Routing Tag for server</param>
9295
/// <param name="isSync">True if the client-side proxy should synchronously invoke the server.</param>
9396
/// <returns>Serialized response from server</returns>
94-
protected override async Task<byte[]> CallDataPortalServer(byte[] serialized, string operation, string routingToken, bool isSync)
97+
protected override async Task<byte[]> CallDataPortalServer(byte[] serialized, string operation, string? routingToken, bool isSync)
9598
{
9699
ByteString outbound = ByteString.CopyFrom(serialized);
97100
var request = new RequestMessage
@@ -112,7 +115,7 @@ internal async Task<ResponseMessage> RouteMessage(RequestMessage request)
112115
return await GetGrpcClient().InvokeAsync(request);
113116
}
114117

115-
private string CreateOperationTag(string operation, string? versionToken, string routingToken)
118+
private string CreateOperationTag(string operation, string? versionToken, string? routingToken)
116119
{
117120
if (!string.IsNullOrWhiteSpace(versionToken) || !string.IsNullOrWhiteSpace(routingToken))
118121
return $"{operation}/{routingToken}-{versionToken}";

Source/Csla.Channels.RabbitMq/Csla.Channels.RabbitMq.csproj

+7
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,13 @@
1717
<PackageReference Include="RabbitMQ.Client" Version="7.0.0" />
1818
</ItemGroup>
1919

20+
<ItemGroup Condition="'$(TargetFramework)'=='netstandard2.1'">
21+
<PackageReference Include="Polyfill" Version="7.4.0">
22+
<PrivateAssets>all</PrivateAssets>
23+
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
24+
</PackageReference>
25+
</ItemGroup>
26+
2027
<ItemGroup>
2128
<ProjectReference Include="..\Csla\Csla.csproj" />
2229
</ItemGroup>

0 commit comments

Comments
 (0)