From b935526a5345eccb698340e56e61b8ba2d403d96 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sat, 5 Dec 2020 23:31:29 +0100 Subject: [PATCH 01/78] Updated dependencies --- src/MongODM.Core/MongODM.Core.csproj | 4 ++-- src/MongODM.Hangfire/MongODM.Hangfire.csproj | 2 +- src/MongODM/MongODM.csproj | 2 +- test/ExecutionContext.Tests/ExecutionContext.Tests.csproj | 4 ++-- test/MongODM.Core.Tests/MongODM.Core.Tests.csproj | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index dca52aed..885601fb 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -31,8 +31,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/src/MongODM.Hangfire/MongODM.Hangfire.csproj b/src/MongODM.Hangfire/MongODM.Hangfire.csproj index bf1885d4..0b5cd779 100644 --- a/src/MongODM.Hangfire/MongODM.Hangfire.csproj +++ b/src/MongODM.Hangfire/MongODM.Hangfire.csproj @@ -26,7 +26,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index 4fd087bf..75d83dc3 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -30,7 +30,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj b/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj index 62a43fd8..70dd6893 100644 --- a/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj +++ b/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj @@ -9,8 +9,8 @@ - - + + all diff --git a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj index e7b435e0..c5093aa1 100644 --- a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj +++ b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj @@ -9,8 +9,8 @@ - - + + all From 02ffbb37f5bc4d9dbb65d2a0d5051b4964a54767 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sun, 31 Jan 2021 14:46:24 +0100 Subject: [PATCH 02/78] Updated dependencies --- src/MongODM.Core/MongODM.Core.csproj | 4 ++-- src/MongODM/MongODM.csproj | 2 +- test/ExecutionContext.Tests/ExecutionContext.Tests.csproj | 2 +- test/MongODM.Core.Tests/MongODM.Core.Tests.csproj | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index 885601fb..cbc563e2 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -31,8 +31,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index 75d83dc3..4d09c92c 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -30,7 +30,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj b/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj index 70dd6893..614345d3 100644 --- a/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj +++ b/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj @@ -10,7 +10,7 @@ - + all diff --git a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj index c5093aa1..02748024 100644 --- a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj +++ b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj @@ -10,7 +10,7 @@ - + all From 06360ccc74d490f47bb0e1c9f81d2c2ae1c0c783 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Fri, 12 Feb 2021 17:22:26 +0100 Subject: [PATCH 03/78] Updated dependencies --- src/ExecutionContext/ExecutionContext.csproj | 2 +- src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj | 2 +- src/MongODM.AspNetCore/MongODM.AspNetCore.csproj | 2 +- src/MongODM.Core/MongODM.Core.csproj | 2 +- src/MongODM.Hangfire/MongODM.Hangfire.csproj | 4 ++-- src/MongODM/MongODM.csproj | 2 +- 6 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/ExecutionContext/ExecutionContext.csproj b/src/ExecutionContext/ExecutionContext.csproj index 9c483c21..d19e6722 100644 --- a/src/ExecutionContext/ExecutionContext.csproj +++ b/src/ExecutionContext/ExecutionContext.csproj @@ -22,7 +22,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj index 5bfc70d0..b608078a 100644 --- a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj +++ b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj @@ -32,7 +32,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj index d7f35519..f369cd99 100644 --- a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj +++ b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj @@ -30,7 +30,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index cbc563e2..f582bdf2 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -23,7 +23,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.Hangfire/MongODM.Hangfire.csproj b/src/MongODM.Hangfire/MongODM.Hangfire.csproj index 0b5cd779..41224c15 100644 --- a/src/MongODM.Hangfire/MongODM.Hangfire.csproj +++ b/src/MongODM.Hangfire/MongODM.Hangfire.csproj @@ -22,11 +22,11 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index 4d09c92c..9bc9a821 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -26,7 +26,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 08d80e645235f68ee4be28c7637b48da84a9b6e8 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Thu, 4 Mar 2021 20:37:24 +0100 Subject: [PATCH 04/78] Fixed VS messages Updated dependencies --- .editorconfig | 14 ++++++++++++++ .../AsyncLocal/AsyncLocalContext.cs | 2 +- .../Domain/Models/DbMigrationOperation.cs | 2 +- src/MongODM.Core/Domain/Models/ModelBase.cs | 2 ++ src/MongODM.Core/Migration/MigrationResult.cs | 4 ++-- src/MongODM.Core/MongODM.Core.csproj | 4 ++-- src/MongODM.Core/MongODMConfiguration.cs | 4 ++-- .../ProxyModels/AuditableInterceptor.cs | 2 +- src/MongODM.Core/ProxyModels/ProxyGenerator.cs | 9 ++++----- .../ProxyModels/ReferenceableInterceptor.cs | 2 +- src/MongODM.Core/ReflectionHelper.cs | 4 ++-- .../Serialization/Mapping/MemberDependency.cs | 2 +- .../Serialization/Mapping/SchemaRegister.cs | 8 ++++++-- .../Mapping/Schemas/ModelMapsSchema.cs | 2 ++ .../Mapping/Schemas/ModelMapsSchemaBase.cs | 2 +- .../Mapping/Schemas/ReferenceModelMapsSchema.cs | 2 ++ src/MongODM.Core/Serialization/SemanticVersion.cs | 4 +++- .../Serializers/ReferenceSerializer.cs | 4 +++- .../ReferenceSerializerConfiguration.cs | 2 ++ .../Tasks/UpdateDocDependenciesTask.cs | 2 +- src/MongODM.Core/Utility/DbDependencies.cs | 2 ++ src/MongODM.Core/Utility/FreezableConfig.cs | 2 +- .../Filters/AsyncLocalContextHangfireFilter.cs | 2 +- .../ExecutionContext.Tests.csproj | 4 ++-- .../ExecutionContextSelectorTests.cs | 4 ++-- .../MockHelpers/InterceptorMockHelper.cs | 4 ++-- test/MongODM.Core.Tests/MongODM.Core.Tests.csproj | 4 ++-- 27 files changed, 65 insertions(+), 34 deletions(-) diff --git a/.editorconfig b/.editorconfig index d04ed153..97bed1a1 100644 --- a/.editorconfig +++ b/.editorconfig @@ -16,3 +16,17 @@ indent_size = 2 # C# files [*.cs] +# CA1014: Mark assemblies with CLSCompliant +dotnet_diagnostic.CA1014.severity = none # Not interested in feature + +# CA1031: Do not catch general exception types +dotnet_diagnostic.CA1031.severity = none + +# CA1040: Avoid empty interfaces +dotnet_diagnostic.CA1040.severity = none # Sometime they are needed + +# CA1063: Implement IDisposable Correctly +dotnet_diagnostic.CA1063.severity = none + +# CA1812: Avoid uninstantiated internal classes +dotnet_diagnostic.CA1812.severity = none # Doing extensive use of dependency injection diff --git a/src/ExecutionContext/AsyncLocal/AsyncLocalContext.cs b/src/ExecutionContext/AsyncLocal/AsyncLocalContext.cs index de765f4d..38b59568 100644 --- a/src/ExecutionContext/AsyncLocal/AsyncLocalContext.cs +++ b/src/ExecutionContext/AsyncLocal/AsyncLocalContext.cs @@ -31,7 +31,7 @@ namespace Etherna.ExecContext.AsyncLocal public class AsyncLocalContext : IAsyncLocalContext, IHandledAsyncLocalContext { // Fields. - private static readonly AsyncLocal?> asyncLocalContext = new AsyncLocal?>(); + private static readonly AsyncLocal?> asyncLocalContext = new(); // Properties. public IDictionary? Items => asyncLocalContext.Value; diff --git a/src/MongODM.Core/Domain/Models/DbMigrationOperation.cs b/src/MongODM.Core/Domain/Models/DbMigrationOperation.cs index 8c87d821..5c931fba 100644 --- a/src/MongODM.Core/Domain/Models/DbMigrationOperation.cs +++ b/src/MongODM.Core/Domain/Models/DbMigrationOperation.cs @@ -31,7 +31,7 @@ public enum Status } // Fields. - private List _logs = new List(); + private List _logs = new(); // Constructors. public DbMigrationOperation(IDbContext dbContext) diff --git a/src/MongODM.Core/Domain/Models/ModelBase.cs b/src/MongODM.Core/Domain/Models/ModelBase.cs index ebc88ba9..e2e79afb 100644 --- a/src/MongODM.Core/Domain/Models/ModelBase.cs +++ b/src/MongODM.Core/Domain/Models/ModelBase.cs @@ -13,11 +13,13 @@ // limitations under the License. using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; namespace Etherna.MongODM.Core.Domain.Models { public abstract class ModelBase : IModel { + [SuppressMessage("Usage", "CA2227:Collection properties should be read only", Justification = "This is needed by MongoDB drivers")] public virtual IDictionary? ExtraElements { get; protected set; } } } diff --git a/src/MongODM.Core/Migration/MigrationResult.cs b/src/MongODM.Core/Migration/MigrationResult.cs index 85cc25b8..962b135f 100644 --- a/src/MongODM.Core/Migration/MigrationResult.cs +++ b/src/MongODM.Core/Migration/MigrationResult.cs @@ -25,13 +25,13 @@ private MigrationResult() { } // Methods. public static MigrationResult Failed() => - new MigrationResult + new() { Succeded = false }; public static MigrationResult Succeeded(long migratedDocuments) => - new MigrationResult + new() { Succeded = true, MigratedDocuments = migratedDocuments diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index f582bdf2..4ac51af2 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -31,8 +31,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/src/MongODM.Core/MongODMConfiguration.cs b/src/MongODM.Core/MongODMConfiguration.cs index 8a979e76..33e5ecee 100644 --- a/src/MongODM.Core/MongODMConfiguration.cs +++ b/src/MongODM.Core/MongODMConfiguration.cs @@ -22,8 +22,8 @@ namespace Etherna.MongODM.Core public abstract class MongODMConfiguration : IMongODMConfiguration, IDisposable { // Fields. - private readonly ReaderWriterLockSlim configLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); - private readonly List _dbContextTypes = new List(); + private readonly ReaderWriterLockSlim configLock = new(LockRecursionPolicy.SupportsRecursion); + private readonly List _dbContextTypes = new(); // Constructor and dispose. public void Dispose() diff --git a/src/MongODM.Core/ProxyModels/AuditableInterceptor.cs b/src/MongODM.Core/ProxyModels/AuditableInterceptor.cs index 0d00b5ca..a5a6d223 100644 --- a/src/MongODM.Core/ProxyModels/AuditableInterceptor.cs +++ b/src/MongODM.Core/ProxyModels/AuditableInterceptor.cs @@ -25,7 +25,7 @@ public class AuditableInterceptor : ModelInterceptorBase { // Fields. private bool isAuditingEnabled; - private readonly HashSet changedMembers = new HashSet(); + private readonly HashSet changedMembers = new(); // Constructors. public AuditableInterceptor(IEnumerable additionalInterfaces) diff --git a/src/MongODM.Core/ProxyModels/ProxyGenerator.cs b/src/MongODM.Core/ProxyModels/ProxyGenerator.cs index b0316ffc..bc717254 100644 --- a/src/MongODM.Core/ProxyModels/ProxyGenerator.cs +++ b/src/MongODM.Core/ProxyModels/ProxyGenerator.cs @@ -27,12 +27,11 @@ public class ProxyGenerator : IProxyGenerator, IDisposable private readonly Castle.DynamicProxy.IProxyGenerator proxyGeneratorCore; private readonly Dictionary InterceptorInstancerSelector)> modelConfigurationDictionary = - new Dictionary InterceptorInstancerSelector)>(); - private readonly ReaderWriterLockSlim modelConfigurationDictionaryLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); + (Type[] AdditionalInterfaces, Func InterceptorInstancerSelector)> modelConfigurationDictionary = new(); + private readonly ReaderWriterLockSlim modelConfigurationDictionaryLock = new(LockRecursionPolicy.SupportsRecursion); - private readonly Dictionary proxyTypeDictionary = new Dictionary(); - private readonly ReaderWriterLockSlim proxyTypeDictionaryLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); + private readonly Dictionary proxyTypeDictionary = new(); + private readonly ReaderWriterLockSlim proxyTypeDictionaryLock = new(LockRecursionPolicy.SupportsRecursion); // Constructors. public ProxyGenerator( diff --git a/src/MongODM.Core/ProxyModels/ReferenceableInterceptor.cs b/src/MongODM.Core/ProxyModels/ReferenceableInterceptor.cs index 1d19e41f..3728f5d3 100644 --- a/src/MongODM.Core/ProxyModels/ReferenceableInterceptor.cs +++ b/src/MongODM.Core/ProxyModels/ReferenceableInterceptor.cs @@ -29,7 +29,7 @@ public class ReferenceableInterceptor : ModelInterceptorBase settedMemberNames = new Dictionary(); // + private readonly Dictionary settedMemberNames = new(); // private readonly IRepository repository; // Constructors. diff --git a/src/MongODM.Core/ReflectionHelper.cs b/src/MongODM.Core/ReflectionHelper.cs index b9869ea7..a20ad33e 100644 --- a/src/MongODM.Core/ReflectionHelper.cs +++ b/src/MongODM.Core/ReflectionHelper.cs @@ -23,8 +23,8 @@ namespace Etherna.MongODM.Core { public static class ReflectionHelper { - private static readonly Dictionary> propertyRegister = new Dictionary>(); - private static readonly ReaderWriterLockSlim propertyRegisterLock = new ReaderWriterLockSlim(); + private static readonly Dictionary> propertyRegister = new(); + private static readonly ReaderWriterLockSlim propertyRegisterLock = new(); public static MemberInfo FindProperty(LambdaExpression lambdaExpression) { diff --git a/src/MongODM.Core/Serialization/Mapping/MemberDependency.cs b/src/MongODM.Core/Serialization/Mapping/MemberDependency.cs index e2115ba7..9584739e 100644 --- a/src/MongODM.Core/Serialization/Mapping/MemberDependency.cs +++ b/src/MongODM.Core/Serialization/Mapping/MemberDependency.cs @@ -132,7 +132,7 @@ public string MemberPathToString() => public override string ToString() { - StringBuilder strBuilder = new StringBuilder(); + StringBuilder strBuilder = new(); strBuilder.AppendLine(FullPathToString()); strBuilder.AppendLine($" modelMapId: {RootModelMap.Id}"); diff --git a/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs b/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs index 8908c05b..c767e488 100644 --- a/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs @@ -20,6 +20,7 @@ using MongoDB.Bson.Serialization; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; using System.Reflection; using System.Text; @@ -66,6 +67,7 @@ public ICustomSerializerSchemaBuilder AddCustomSerializerSchema( return modelSchemaConfiguration; }); + [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The new model map instance can't be disposed")] public IModelMapsSchemaBuilder AddModelMapsSchema( string activeModelMapId, Action>? activeModelMapInitializer = null, @@ -158,7 +160,7 @@ public IModelMapsSchema GetModelMapsSchema(Type modelType) public override string ToString() { - StringBuilder strBuilder = new StringBuilder(); + StringBuilder strBuilder = new(); // Member dependencies. //memberInfoToMemberMapsDictionary @@ -308,7 +310,9 @@ private void CompileDependencyRegisters( //model maps schema serializers if (memberSerializer is IModelMapsContainerSerializer schemaSerializer) { - var useCascadeDelete = (memberSerializer as IReferenceContainerSerializer)?.UseCascadeDelete; +#pragma warning disable CA1508 // Avoid dead conditional code. Here code analyzer is wrong + bool? useCascadeDelete = (memberSerializer as IReferenceContainerSerializer)?.UseCascadeDelete; +#pragma warning restore CA1508 // Avoid dead conditional code foreach (var childClassMap in schemaSerializer.AllChildClassMaps) CompileDependencyRegisters(modelMap, childClassMap, lastEntityClassMap, currentMemberPath, useCascadeDelete); } diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchema.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchema.cs index ff34238f..68a07b4c 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchema.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchema.cs @@ -14,6 +14,7 @@ using MongoDB.Bson.Serialization; using System; +using System.Diagnostics.CodeAnalysis; namespace Etherna.MongODM.Core.Serialization.Mapping.Schemas { @@ -34,6 +35,7 @@ public IModelMapsSchemaBuilder AddFallbackCustomSerializer(IBsonSerializ return this; } + [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The new model map instance can't be disposed")] public IModelMapsSchemaBuilder AddSecondaryMap( string id, Action>? modelMapInitializer = null, diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchemaBase.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchemaBase.cs index 96afc265..a208a8cf 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchemaBase.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchemaBase.cs @@ -23,7 +23,7 @@ abstract class ModelMapsSchemaBase : SchemaBase, IModelMapsSchema { // Fields. private Dictionary _allMapsDictionary = default!; - protected readonly List _secondaryMaps = new List(); + protected readonly List _secondaryMaps = new(); // Constructor. protected ModelMapsSchemaBase( diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/ReferenceModelMapsSchema.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/ReferenceModelMapsSchema.cs index 225e81a8..3f925241 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/ReferenceModelMapsSchema.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/ReferenceModelMapsSchema.cs @@ -14,6 +14,7 @@ using MongoDB.Bson.Serialization; using System; +using System.Diagnostics.CodeAnalysis; namespace Etherna.MongODM.Core.Serialization.Mapping.Schemas { @@ -33,6 +34,7 @@ public IReferenceModelMapsSchemaBuilder AddFallbackCustomSerializer(IBso return this; } + [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The new model map instance can't be disposed")] public IReferenceModelMapsSchemaBuilder AddSecondaryMap( string id, string? baseModelMapId = null, diff --git a/src/MongODM.Core/Serialization/SemanticVersion.cs b/src/MongODM.Core/Serialization/SemanticVersion.cs index 44bb2a04..488fea21 100644 --- a/src/MongODM.Core/Serialization/SemanticVersion.cs +++ b/src/MongODM.Core/Serialization/SemanticVersion.cs @@ -173,6 +173,8 @@ public override string ToString() public static bool operator >=(SemanticVersion x, SemanticVersion y) => y <= x; - public static implicit operator SemanticVersion(string version) => new SemanticVersion(version); + public static implicit operator SemanticVersion(string version) => new(version); + + public static SemanticVersion FromString(string version) => new(version); } } diff --git a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs index 07c61071..343675b9 100644 --- a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs @@ -38,7 +38,7 @@ public class ReferenceSerializer : // Fields. private IDiscriminatorConvention _discriminatorConvention = default!; - private readonly ReaderWriterLockSlim configLockAdapters = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); + private readonly ReaderWriterLockSlim configLockAdapters = new(LockRecursionPolicy.SupportsRecursion); private readonly IDbContext dbContext; private readonly ReferenceSerializerConfiguration configuration; private readonly IDictionary registeredAdapters = new Dictionary(); @@ -138,8 +138,10 @@ public override TModelBase Deserialize(BsonDeserializationContext context, BsonD if (model != null) { var id = model.Id; +#pragma warning disable CA1508 // Avoid dead conditional code if (id == null) //ignore refered instances without id return null!; +#pragma warning restore CA1508 // Avoid dead conditional code // Check if model as been loaded in cache. if (dbContext.DbCache.LoadedModels.ContainsKey(id) && diff --git a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerConfiguration.cs b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerConfiguration.cs index eb3a840c..d62fb096 100644 --- a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerConfiguration.cs +++ b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerConfiguration.cs @@ -19,6 +19,7 @@ using MongoDB.Bson.Serialization; using System; using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; using System.Linq; namespace Etherna.MongODM.Core.Serialization.Serializers @@ -48,6 +49,7 @@ public bool UseCascadeDelete } // Methods. + [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The new model map instance can't be disposed")] public IReferenceModelMapsSchemaBuilder AddModelMapsSchema( string activeModelMapId, Action>? activeModelMapInitializer = null, diff --git a/src/MongODM.Core/Tasks/UpdateDocDependenciesTask.cs b/src/MongODM.Core/Tasks/UpdateDocDependenciesTask.cs index 4405070b..da017e79 100644 --- a/src/MongODM.Core/Tasks/UpdateDocDependenciesTask.cs +++ b/src/MongODM.Core/Tasks/UpdateDocDependenciesTask.cs @@ -57,7 +57,7 @@ public async Task RunAsync( var repository = (ICollectionRepository)dbContext.RepositoryRegister.ModelCollectionRepositoryMap[typeof(TModel)]; // Update models. - HashSet upgradedDocumentsId = new HashSet(); + HashSet upgradedDocumentsId = new(); using (serializerModifierAccessor.EnableReferenceSerializerModifier(true)) using (serializerModifierAccessor.EnableCacheSerializerModifier(true)) { diff --git a/src/MongODM.Core/Utility/DbDependencies.cs b/src/MongODM.Core/Utility/DbDependencies.cs index 5ade06b5..ff8e3af5 100644 --- a/src/MongODM.Core/Utility/DbDependencies.cs +++ b/src/MongODM.Core/Utility/DbDependencies.cs @@ -30,7 +30,9 @@ public DbDependencies( ISchemaRegister schemaRegister, ISerializerModifierAccessor serializerModifierAccessor, #pragma warning disable IDE0060 // Remove unused parameter. It's needed for run static configurations +#pragma warning disable CA1801 // Review unused parameters IStaticConfigurationBuilder staticConfigurationBuilder) +#pragma warning restore CA1801 // Review unused parameters #pragma warning restore IDE0060 // Remove unused parameter { DbCache = dbCache; diff --git a/src/MongODM.Core/Utility/FreezableConfig.cs b/src/MongODM.Core/Utility/FreezableConfig.cs index b335a93b..8e1dfdb3 100644 --- a/src/MongODM.Core/Utility/FreezableConfig.cs +++ b/src/MongODM.Core/Utility/FreezableConfig.cs @@ -20,7 +20,7 @@ namespace Etherna.MongODM.Core.Utility public abstract class FreezableConfig : IFreezableConfig, IDisposable { // Fields. - private readonly ReaderWriterLockSlim configLock = new ReaderWriterLockSlim(LockRecursionPolicy.SupportsRecursion); + private readonly ReaderWriterLockSlim configLock = new(LockRecursionPolicy.SupportsRecursion); // Dispose. public void Dispose() diff --git a/src/MongODM.Hangfire/Filters/AsyncLocalContextHangfireFilter.cs b/src/MongODM.Hangfire/Filters/AsyncLocalContextHangfireFilter.cs index 9191b995..0445c848 100644 --- a/src/MongODM.Hangfire/Filters/AsyncLocalContextHangfireFilter.cs +++ b/src/MongODM.Hangfire/Filters/AsyncLocalContextHangfireFilter.cs @@ -22,7 +22,7 @@ namespace Etherna.MongODM.HF.Filters public class AsyncLocalContextHangfireFilter : IServerFilter { // Fields. - private readonly Dictionary contextHandlers = new Dictionary(); + private readonly Dictionary contextHandlers = new(); private readonly IAsyncLocalContext asyncLocalContext; // Constructors. diff --git a/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj b/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj index 614345d3..fabb5628 100644 --- a/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj +++ b/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj @@ -9,8 +9,8 @@ - - + + all diff --git a/test/ExecutionContext.Tests/ExecutionContextSelectorTests.cs b/test/ExecutionContext.Tests/ExecutionContextSelectorTests.cs index 3a6699f3..5310ed92 100644 --- a/test/ExecutionContext.Tests/ExecutionContextSelectorTests.cs +++ b/test/ExecutionContext.Tests/ExecutionContextSelectorTests.cs @@ -32,8 +32,8 @@ public void ContextSelection( string expectedResult) { // Setup. - Mock context0 = new Mock(); - Mock context1 = new Mock(); + Mock context0 = new(); + Mock context1 = new(); context0.SetupGet(c => c.Items) .Returns(enableContext1 ? new Dictionary { { "val", "0" } } : null); context1.SetupGet(c => c.Items) diff --git a/test/MongODM.Core.Tests/MockHelpers/InterceptorMockHelper.cs b/test/MongODM.Core.Tests/MockHelpers/InterceptorMockHelper.cs index e3447bb9..6b5737ad 100644 --- a/test/MongODM.Core.Tests/MockHelpers/InterceptorMockHelper.cs +++ b/test/MongODM.Core.Tests/MockHelpers/InterceptorMockHelper.cs @@ -45,7 +45,7 @@ public static class InterceptorMockHelper public static Mock GetExternalPropertyGetInvocationMock( Expression> memberLambda, TProxy? proxyModel = null, - TMember returnValue = default) + TMember? returnValue = default) where TProxy : class { var invocation = GetInvocationMock(proxyModel); @@ -95,7 +95,7 @@ public static class InterceptorMockHelper public static Mock GetPropertyGetInvocationMock( Expression> memberLambda, TProxy? proxyModel = null, - TMember returnValue = default) + TMember? returnValue = default) where TProxy : class { return GetExternalPropertyGetInvocationMock(memberLambda, proxyModel, returnValue!); diff --git a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj index 02748024..27f0f0ea 100644 --- a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj +++ b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj @@ -9,8 +9,8 @@ - - + + all From 6ac1f60d7bf2fd416c68d4f814622fd2c7037df1 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sat, 27 Mar 2021 20:43:36 +0100 Subject: [PATCH 05/78] Updated dependencies --- src/MongODM.Core/MongODM.Core.csproj | 4 ++-- src/MongODM.Hangfire/MongODM.Hangfire.csproj | 2 +- src/MongODM/MongODM.csproj | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index 4ac51af2..39bcd154 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -31,8 +31,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/src/MongODM.Hangfire/MongODM.Hangfire.csproj b/src/MongODM.Hangfire/MongODM.Hangfire.csproj index 41224c15..bebbd99b 100644 --- a/src/MongODM.Hangfire/MongODM.Hangfire.csproj +++ b/src/MongODM.Hangfire/MongODM.Hangfire.csproj @@ -26,7 +26,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index 9bc9a821..934f2e6b 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -30,7 +30,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 34238c724208fa27161e897e1235332629b7fc6c Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sun, 2 May 2021 19:20:17 +0200 Subject: [PATCH 06/78] Updated dependencies --- src/ExecutionContext/ExecutionContext.csproj | 2 +- src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj | 2 +- src/MongODM.AspNetCore/MongODM.AspNetCore.csproj | 2 +- src/MongODM.Core/MongODM.Core.csproj | 6 +++--- src/MongODM.Hangfire/MongODM.Hangfire.csproj | 4 ++-- src/MongODM/MongODM.csproj | 4 ++-- test/ExecutionContext.Tests/ExecutionContext.Tests.csproj | 2 +- test/MongODM.Core.Tests/MongODM.Core.Tests.csproj | 2 +- 8 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/ExecutionContext/ExecutionContext.csproj b/src/ExecutionContext/ExecutionContext.csproj index d19e6722..930dd300 100644 --- a/src/ExecutionContext/ExecutionContext.csproj +++ b/src/ExecutionContext/ExecutionContext.csproj @@ -22,7 +22,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj index b608078a..2289e5f8 100644 --- a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj +++ b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj @@ -32,7 +32,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj index f369cd99..217d643f 100644 --- a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj +++ b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj @@ -30,7 +30,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index 39bcd154..a51c00d1 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -23,7 +23,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -31,8 +31,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/src/MongODM.Hangfire/MongODM.Hangfire.csproj b/src/MongODM.Hangfire/MongODM.Hangfire.csproj index bebbd99b..69688184 100644 --- a/src/MongODM.Hangfire/MongODM.Hangfire.csproj +++ b/src/MongODM.Hangfire/MongODM.Hangfire.csproj @@ -22,11 +22,11 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index 934f2e6b..9d8b17e6 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -26,11 +26,11 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj b/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj index fabb5628..063d10da 100644 --- a/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj +++ b/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj index 27f0f0ea..f470492f 100644 --- a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj +++ b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj @@ -9,7 +9,7 @@ - + From 5d77a15431fab76fafc83f40b1e44d592874dfa2 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sun, 2 May 2021 19:59:00 +0200 Subject: [PATCH 07/78] Fixed .net diagnostic CA1014 Fixed .net diagnostic CA1063 --- .editorconfig | 6 ---- .../Properties/AssemblyInfo.cs | 2 ++ .../Properties/AssemblyInfo.cs | 17 +++++++++++ src/MongODM.Core/MongODMConfiguration.cs | 16 ++++++++-- src/MongODM.Core/Properties/AssemblyInfo.cs | 17 +++++++++++ .../ProxyModels/ProxyGenerator.cs | 29 ++++++++++++++----- .../Serializers/ReferenceSerializer.cs | 21 ++++++++++++-- src/MongODM.Core/Utility/FreezableConfig.cs | 14 ++++++++- .../Properties/AssemblyInfo.cs | 17 +++++++++++ 9 files changed, 120 insertions(+), 19 deletions(-) create mode 100644 src/MongODM.AspNetCore.UI/Properties/AssemblyInfo.cs create mode 100644 src/MongODM.Core/Properties/AssemblyInfo.cs create mode 100644 src/MongODM.Hangfire/Properties/AssemblyInfo.cs diff --git a/.editorconfig b/.editorconfig index 97bed1a1..1b9ef798 100644 --- a/.editorconfig +++ b/.editorconfig @@ -16,17 +16,11 @@ indent_size = 2 # C# files [*.cs] -# CA1014: Mark assemblies with CLSCompliant -dotnet_diagnostic.CA1014.severity = none # Not interested in feature - # CA1031: Do not catch general exception types dotnet_diagnostic.CA1031.severity = none # CA1040: Avoid empty interfaces dotnet_diagnostic.CA1040.severity = none # Sometime they are needed -# CA1063: Implement IDisposable Correctly -dotnet_diagnostic.CA1063.severity = none - # CA1812: Avoid uninstantiated internal classes dotnet_diagnostic.CA1812.severity = none # Doing extensive use of dependency injection diff --git a/src/ExecutionContext/Properties/AssemblyInfo.cs b/src/ExecutionContext/Properties/AssemblyInfo.cs index 17f09a54..3a8ab07a 100644 --- a/src/ExecutionContext/Properties/AssemblyInfo.cs +++ b/src/ExecutionContext/Properties/AssemblyInfo.cs @@ -12,7 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +using System; using System.Runtime.CompilerServices; +[assembly: CLSCompliant(false)] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] [assembly: InternalsVisibleTo("ExecutionContext.Tests")] diff --git a/src/MongODM.AspNetCore.UI/Properties/AssemblyInfo.cs b/src/MongODM.AspNetCore.UI/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..dd2b8d00 --- /dev/null +++ b/src/MongODM.AspNetCore.UI/Properties/AssemblyInfo.cs @@ -0,0 +1,17 @@ +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; + +[assembly: CLSCompliant(false)] \ No newline at end of file diff --git a/src/MongODM.Core/MongODMConfiguration.cs b/src/MongODM.Core/MongODMConfiguration.cs index 33e5ecee..13380df8 100644 --- a/src/MongODM.Core/MongODMConfiguration.cs +++ b/src/MongODM.Core/MongODMConfiguration.cs @@ -23,15 +23,27 @@ public abstract class MongODMConfiguration : IMongODMConfiguration, IDisposable { // Fields. private readonly ReaderWriterLockSlim configLock = new(LockRecursionPolicy.SupportsRecursion); + private bool disposed; private readonly List _dbContextTypes = new(); - // Constructor and dispose. + // Dispose. public void Dispose() { - configLock.Dispose(); + Dispose(true); GC.SuppressFinalize(this); } + protected virtual void Dispose(bool disposing) + { + if (disposed) return; + + // Dispose managed resources. + if (disposing) + configLock.Dispose(); + + disposed = true; + } + // Properties. public IEnumerable DbContextTypes { diff --git a/src/MongODM.Core/Properties/AssemblyInfo.cs b/src/MongODM.Core/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..dd2b8d00 --- /dev/null +++ b/src/MongODM.Core/Properties/AssemblyInfo.cs @@ -0,0 +1,17 @@ +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; + +[assembly: CLSCompliant(false)] \ No newline at end of file diff --git a/src/MongODM.Core/ProxyModels/ProxyGenerator.cs b/src/MongODM.Core/ProxyModels/ProxyGenerator.cs index bc717254..7cfd148d 100644 --- a/src/MongODM.Core/ProxyModels/ProxyGenerator.cs +++ b/src/MongODM.Core/ProxyModels/ProxyGenerator.cs @@ -24,6 +24,7 @@ namespace Etherna.MongODM.Core.ProxyModels public class ProxyGenerator : IProxyGenerator, IDisposable { // Fields. + private bool disposed; private readonly Castle.DynamicProxy.IProxyGenerator proxyGeneratorCore; private readonly Dictionary(IDbContext dbContext, params object[] constructorArguments) => (TModel)CreateInstance(typeof(TModel), dbContext, constructorArguments); - public void Dispose() - { - modelConfigurationDictionaryLock.Dispose(); - proxyTypeDictionaryLock.Dispose(); - GC.SuppressFinalize(this); - } - public bool IsProxyType(Type type) { proxyTypeDictionaryLock.EnterReadLock(); diff --git a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs index 343675b9..dd993c27 100644 --- a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs @@ -40,10 +40,11 @@ public class ReferenceSerializer : private readonly ReaderWriterLockSlim configLockAdapters = new(LockRecursionPolicy.SupportsRecursion); private readonly IDbContext dbContext; + private bool disposed; private readonly ReferenceSerializerConfiguration configuration; private readonly IDictionary registeredAdapters = new Dictionary(); - // Constructor and dispose. + // Constructor. public ReferenceSerializer( IDbContext dbContext, Action configure) @@ -58,13 +59,27 @@ public ReferenceSerializer( configuration.Freeze(); } + // Dispose. public void Dispose() { - configLockAdapters.Dispose(); - configuration.Dispose(); + Dispose(true); GC.SuppressFinalize(this); } + protected virtual void Dispose(bool disposing) + { + if (disposed) return; + + // Dispose managed resources. + if (disposing) + { + configLockAdapters.Dispose(); + configuration.Dispose(); + } + + disposed = true; + } + // Properties. public IEnumerable AllChildClassMaps => configuration.Schemas.Values .SelectMany(schema => schema.AllMapsDictionary.Values diff --git a/src/MongODM.Core/Utility/FreezableConfig.cs b/src/MongODM.Core/Utility/FreezableConfig.cs index 8e1dfdb3..5369c4dc 100644 --- a/src/MongODM.Core/Utility/FreezableConfig.cs +++ b/src/MongODM.Core/Utility/FreezableConfig.cs @@ -21,14 +21,26 @@ public abstract class FreezableConfig : IFreezableConfig, IDisposable { // Fields. private readonly ReaderWriterLockSlim configLock = new(LockRecursionPolicy.SupportsRecursion); + private bool disposed; // Dispose. public void Dispose() { - configLock.Dispose(); + Dispose(true); GC.SuppressFinalize(this); } + protected virtual void Dispose(bool disposing) + { + if (disposed) return; + + // Dispose managed resources. + if (disposing) + configLock.Dispose(); + + disposed = true; + } + // Properties. public bool IsFrozen { get; private set; } diff --git a/src/MongODM.Hangfire/Properties/AssemblyInfo.cs b/src/MongODM.Hangfire/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..dd2b8d00 --- /dev/null +++ b/src/MongODM.Hangfire/Properties/AssemblyInfo.cs @@ -0,0 +1,17 @@ +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; + +[assembly: CLSCompliant(false)] \ No newline at end of file From b5ae4fd29b2773371724d2481b7452f93cb89c45 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Mon, 19 Jul 2021 23:32:37 +0200 Subject: [PATCH 08/78] Updated dependencies --- src/ExecutionContext/ExecutionContext.csproj | 2 +- src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj | 2 +- src/MongODM.AspNetCore/MongODM.AspNetCore.csproj | 2 +- src/MongODM.Core/MongODM.Core.csproj | 6 +++--- src/MongODM.Hangfire/MongODM.Hangfire.csproj | 2 +- src/MongODM/MongODM.csproj | 4 ++-- test/ExecutionContext.Tests/ExecutionContext.Tests.csproj | 2 +- test/MongODM.Core.Tests/MongODM.Core.Tests.csproj | 2 +- 8 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/ExecutionContext/ExecutionContext.csproj b/src/ExecutionContext/ExecutionContext.csproj index 930dd300..2a6513fc 100644 --- a/src/ExecutionContext/ExecutionContext.csproj +++ b/src/ExecutionContext/ExecutionContext.csproj @@ -22,7 +22,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj index 2289e5f8..e8e85c93 100644 --- a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj +++ b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj @@ -32,7 +32,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj index 217d643f..5805ba8f 100644 --- a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj +++ b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj @@ -30,7 +30,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index a51c00d1..a6d89a5e 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -23,7 +23,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -31,8 +31,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/src/MongODM.Hangfire/MongODM.Hangfire.csproj b/src/MongODM.Hangfire/MongODM.Hangfire.csproj index 69688184..cc5a8b9f 100644 --- a/src/MongODM.Hangfire/MongODM.Hangfire.csproj +++ b/src/MongODM.Hangfire/MongODM.Hangfire.csproj @@ -22,7 +22,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index 9d8b17e6..075dc3ad 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -26,11 +26,11 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj b/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj index 063d10da..5628302f 100644 --- a/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj +++ b/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj @@ -9,7 +9,7 @@ - + diff --git a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj index f470492f..10245eac 100644 --- a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj +++ b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj @@ -9,7 +9,7 @@ - + From ea5ab6d44dab9920a4b2cf088469606f1307c7fe Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Wed, 21 Jul 2021 01:28:21 +0200 Subject: [PATCH 09/78] Updated stable release workflow to main branch --- .github/workflows/nuget-stable-deploy.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nuget-stable-deploy.yml b/.github/workflows/nuget-stable-deploy.yml index 395d261b..cb97bcd4 100644 --- a/.github/workflows/nuget-stable-deploy.yml +++ b/.github/workflows/nuget-stable-deploy.yml @@ -3,7 +3,7 @@ name: Stable release deploy to NuGet on: push: branches: - - master + - main jobs: build-test-package: From e98a8c049566f65f791c33c69eea586b6eee7ba8 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Fri, 23 Jul 2021 20:58:55 +0200 Subject: [PATCH 10/78] Implemented use of options pattern --- .../Persistence/SampleDbContext.cs | 5 +- samples/AspNetCoreSample/Startup.cs | 1 + .../Areas/MongODM/Pages/Index.cshtml.cs | 15 ++-- .../MongODM.AspNetCore.UI.csproj | 8 +-- .../ServiceCollectionExtensions.cs | 4 +- .../AspNetCoreMongODMConfiguration.cs | 45 ------------ .../DbDependencies.cs | 20 ++++-- .../IMongODMConfiguration.cs | 11 ++- .../MongODMConfiguration.cs | 71 ++++++++----------- .../ServiceCollectionExtensions.cs | 43 +++++++---- .../StaticConfigurationBuilder.cs | 41 ----------- src/MongODM.Core/Options/DbContextOptions.cs | 35 +++++---- src/MongODM.Core/Options/MongODMOptions.cs | 11 ++- .../Options/MongODMOptionsBuilder.cs | 10 +++ src/MongODM.Core/Tasks/ITaskRunnerBuilder.cs | 9 +++ .../Utility/IStaticConfigurationBuilder.cs | 26 ------- .../Tasks/HangfireTaskRunner.cs | 14 ++-- src/MongODM/ServiceCollectionExtensions.cs | 6 +- 18 files changed, 159 insertions(+), 216 deletions(-) delete mode 100644 src/MongODM.AspNetCore/AspNetCoreMongODMConfiguration.cs rename src/{MongODM.Core/Utility => MongODM.AspNetCore}/DbDependencies.cs (81%) rename src/{MongODM.Core => MongODM.AspNetCore}/IMongODMConfiguration.cs (79%) rename src/{MongODM.Core => MongODM.AspNetCore}/MongODMConfiguration.cs (63%) delete mode 100644 src/MongODM.AspNetCore/StaticConfigurationBuilder.cs create mode 100644 src/MongODM.Core/Options/MongODMOptionsBuilder.cs create mode 100644 src/MongODM.Core/Tasks/ITaskRunnerBuilder.cs delete mode 100644 src/MongODM.Core/Utility/IStaticConfigurationBuilder.cs diff --git a/samples/AspNetCoreSample/Persistence/SampleDbContext.cs b/samples/AspNetCoreSample/Persistence/SampleDbContext.cs index 00b47524..98c2c1e1 100644 --- a/samples/AspNetCoreSample/Persistence/SampleDbContext.cs +++ b/samples/AspNetCoreSample/Persistence/SampleDbContext.cs @@ -18,6 +18,7 @@ using Etherna.MongODM.Core.Options; using Etherna.MongODM.Core.Repositories; using Etherna.MongODM.Core.Serialization; +using Microsoft.Extensions.Options; using System.Collections.Generic; namespace Etherna.MongODM.AspNetCoreSample.Persistence @@ -26,8 +27,8 @@ public class SampleDbContext : DbContext, ISampleDbContext { public SampleDbContext( IDbDependencies dependencies, - DbContextOptions options) - : base(dependencies, options) + IOptionsMonitor options) + : base(dependencies, options.Get(nameof(ISampleDbContext))) { } public ICollectionRepository Cats { get; } = new CollectionRepository("cats"); diff --git a/samples/AspNetCoreSample/Startup.cs b/samples/AspNetCoreSample/Startup.cs index 8a34c1cd..d81776ef 100644 --- a/samples/AspNetCoreSample/Startup.cs +++ b/samples/AspNetCoreSample/Startup.cs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongODM.AspNetCore.UI; using Etherna.MongODM.AspNetCoreSample.Models; using Etherna.MongODM.AspNetCoreSample.Persistence; using Hangfire; diff --git a/src/MongODM.AspNetCore.UI/Areas/MongODM/Pages/Index.cshtml.cs b/src/MongODM.AspNetCore.UI/Areas/MongODM/Pages/Index.cshtml.cs index e3c93c18..e6d9aa8b 100644 --- a/src/MongODM.AspNetCore.UI/Areas/MongODM/Pages/Index.cshtml.cs +++ b/src/MongODM.AspNetCore.UI/Areas/MongODM/Pages/Index.cshtml.cs @@ -13,8 +13,10 @@ // limitations under the License. using Etherna.MongODM.Core; +using Etherna.MongODM.Core.Options; using Microsoft.AspNetCore.Mvc.RazorPages; using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using System; using System.Collections.Generic; using System.Linq; @@ -25,16 +27,19 @@ namespace Etherna.MongODM.AspNetCore.UI.Areas.MongODM.Pages public class IndexModel : PageModel { // Fields. - private readonly IMongODMConfiguration configuration; + private readonly MongODMOptions options; private readonly IServiceProvider serviceProvider; // Constructor. public IndexModel( - IMongODMConfiguration configuration, + IOptions options, IServiceProvider serviceProvider) { - this.configuration = configuration ?? throw new ArgumentNullException(nameof(configuration)); - this.serviceProvider = serviceProvider ?? throw new ArgumentNullException(nameof(serviceProvider)); + if (options is null) + throw new ArgumentNullException(nameof(options)); + + this.options = options.Value; + this.serviceProvider = serviceProvider; } // Properties. @@ -61,7 +66,7 @@ public async Task OnPostAsync(string identifier) private void InitializePage() { // Get dbcontext instances. - var dbContextTypes = configuration.DbContextTypes; + var dbContextTypes = options.DbContextTypes; DbContexts = dbContextTypes.Select(type => (IDbContext)serviceProvider.GetRequiredService(type)); } } diff --git a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj index e8e85c93..21953251 100644 --- a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj +++ b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj @@ -42,10 +42,6 @@ - - - - True @@ -53,4 +49,8 @@ + + + + diff --git a/src/MongODM.AspNetCore.UI/ServiceCollectionExtensions.cs b/src/MongODM.AspNetCore.UI/ServiceCollectionExtensions.cs index ff954a57..82548a1b 100644 --- a/src/MongODM.AspNetCore.UI/ServiceCollectionExtensions.cs +++ b/src/MongODM.AspNetCore.UI/ServiceCollectionExtensions.cs @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -using Etherna.MongODM.AspNetCore.UI; using Etherna.MongODM.AspNetCore.UI.Auth.Handlers; using Etherna.MongODM.AspNetCore.UI.Auth.Requirements; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc.RazorPages; +using Microsoft.Extensions.DependencyInjection; using System; -namespace Microsoft.Extensions.DependencyInjection +namespace Etherna.MongODM.AspNetCore.UI { public static class ServiceCollectionExtensions { diff --git a/src/MongODM.AspNetCore/AspNetCoreMongODMConfiguration.cs b/src/MongODM.AspNetCore/AspNetCoreMongODMConfiguration.cs deleted file mode 100644 index f4618de9..00000000 --- a/src/MongODM.AspNetCore/AspNetCoreMongODMConfiguration.cs +++ /dev/null @@ -1,45 +0,0 @@ -// Copyright 2020-present Etherna Sagl -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using Etherna.MongODM.Core; -using Microsoft.Extensions.DependencyInjection; -using System; - -namespace Etherna.MongODM.AspNetCore -{ - public class AspNetCoreMongODMConfiguration : MongODMConfiguration - { - // Fields. - private readonly IServiceCollection services; - - // Constructor. - public AspNetCoreMongODMConfiguration(IServiceCollection services) - { - this.services = services; - } - - // Protected methods. - protected override void RegisterSingleton() => - services.AddSingleton(); - - protected override void RegisterSingleton(TService instance) => - services.AddSingleton(instance); - - protected override void RegisterSingleton() => - services.AddSingleton(); - - protected override void RegisterSingleton(Func implementationFactory) => - services.AddSingleton(implementationFactory); - } -} diff --git a/src/MongODM.Core/Utility/DbDependencies.cs b/src/MongODM.AspNetCore/DbDependencies.cs similarity index 81% rename from src/MongODM.Core/Utility/DbDependencies.cs rename to src/MongODM.AspNetCore/DbDependencies.cs index ff8e3af5..349e1aca 100644 --- a/src/MongODM.Core/Utility/DbDependencies.cs +++ b/src/MongODM.AspNetCore/DbDependencies.cs @@ -12,12 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongODM.Core; +using Etherna.MongODM.Core.Options; using Etherna.MongODM.Core.ProxyModels; using Etherna.MongODM.Core.Repositories; using Etherna.MongODM.Core.Serialization.Mapping; using Etherna.MongODM.Core.Serialization.Modifiers; +using Etherna.MongODM.Core.Utility; +using Microsoft.Extensions.Options; +using System; -namespace Etherna.MongODM.Core.Utility +namespace Etherna.MongODM.AspNetCore { public class DbDependencies : IDbDependencies { @@ -25,19 +30,19 @@ public DbDependencies( IDbCache dbCache, IDbMaintainer dbMaintainer, IDbMigrationManager dbContextMigrationManager, + IOptions mongODMOptions, IProxyGenerator proxyGenerator, IRepositoryRegister repositoryRegister, ISchemaRegister schemaRegister, - ISerializerModifierAccessor serializerModifierAccessor, -#pragma warning disable IDE0060 // Remove unused parameter. It's needed for run static configurations -#pragma warning disable CA1801 // Review unused parameters - IStaticConfigurationBuilder staticConfigurationBuilder) -#pragma warning restore CA1801 // Review unused parameters -#pragma warning restore IDE0060 // Remove unused parameter + ISerializerModifierAccessor serializerModifierAccessor) { + if (mongODMOptions is null) + throw new ArgumentNullException(nameof(mongODMOptions)); + DbCache = dbCache; DbMaintainer = dbMaintainer; DbMigrationManager = dbContextMigrationManager; + MongODMOptions = mongODMOptions.Value; SchemaRegister = schemaRegister; ProxyGenerator = proxyGenerator; RepositoryRegister = repositoryRegister; @@ -47,6 +52,7 @@ public DbDependencies( public IDbCache DbCache { get; } public IDbMaintainer DbMaintainer { get; } public IDbMigrationManager DbMigrationManager { get; } + public MongODMOptions MongODMOptions { get; } public IProxyGenerator ProxyGenerator { get; } public IRepositoryRegister RepositoryRegister { get; } public ISchemaRegister SchemaRegister { get; } diff --git a/src/MongODM.Core/IMongODMConfiguration.cs b/src/MongODM.AspNetCore/IMongODMConfiguration.cs similarity index 79% rename from src/MongODM.Core/IMongODMConfiguration.cs rename to src/MongODM.AspNetCore/IMongODMConfiguration.cs index c2d2f34b..15e778fd 100644 --- a/src/MongODM.Core/IMongODMConfiguration.cs +++ b/src/MongODM.AspNetCore/IMongODMConfiguration.cs @@ -12,30 +12,29 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongODM.Core; using Etherna.MongODM.Core.Options; using System; -using System.Collections.Generic; -namespace Etherna.MongODM.Core +namespace Etherna.MongODM.AspNetCore { public interface IMongODMConfiguration { - IEnumerable DbContextTypes { get; } bool IsFrozen { get; } // Methods. IMongODMConfiguration AddDbContext( - Action>? dbContextConfig = null) + Action? dbContextConfig = null) where TDbContext : class, IDbContext; IMongODMConfiguration AddDbContext( - Action>? dbContextConfig = null) + Action? dbContextConfig = null) where TDbContext : class, IDbContext where TDbContextImpl : class, TDbContext; /// /// Freeze configuration. /// - void Freeze(); + void Freeze(IMongODMOptionsBuilder mongODMOptionsBuilder); } } diff --git a/src/MongODM.Core/MongODMConfiguration.cs b/src/MongODM.AspNetCore/MongODMConfiguration.cs similarity index 63% rename from src/MongODM.Core/MongODMConfiguration.cs rename to src/MongODM.AspNetCore/MongODMConfiguration.cs index 13380df8..d5f21575 100644 --- a/src/MongODM.Core/MongODMConfiguration.cs +++ b/src/MongODM.AspNetCore/MongODMConfiguration.cs @@ -12,19 +12,29 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongODM.Core; using Etherna.MongODM.Core.Options; +using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; using System.Threading; -namespace Etherna.MongODM.Core +namespace Etherna.MongODM.AspNetCore { - public abstract class MongODMConfiguration : IMongODMConfiguration, IDisposable + public class MongODMConfiguration : IMongODMConfiguration, IDisposable { // Fields. private readonly ReaderWriterLockSlim configLock = new(LockRecursionPolicy.SupportsRecursion); + private readonly List dbContextTypes = new(); private bool disposed; - private readonly List _dbContextTypes = new(); + private readonly IServiceCollection services; + + // Constructor. + public MongODMConfiguration( + IServiceCollection services) + { + this.services = services; + } // Dispose. public void Dispose() @@ -45,21 +55,11 @@ protected virtual void Dispose(bool disposing) } // Properties. - public IEnumerable DbContextTypes - { - get - { - Freeze(); - return _dbContextTypes; - } - } - public bool IsFrozen { get; private set; } // Methods. - public IMongODMConfiguration AddDbContext( - Action>? dbContextConfig = null) + Action? dbContextConfig = null) where TDbContext : class, IDbContext { configLock.EnterWriteLock(); @@ -69,15 +69,14 @@ public IMongODMConfiguration AddDbContext( throw new InvalidOperationException("Configuration is frozen"); // Register dbContext. - RegisterSingleton(); + services.AddSingleton(); // Register options. - var contextOptions = new DbContextOptions(); - dbContextConfig?.Invoke(contextOptions); - RegisterSingleton(contextOptions); + services.AddOptions(typeof(TDbContext).Name) + .Configure(dbContextConfig ?? (_ => { })); // Add db context type. - _dbContextTypes.Add(typeof(TDbContext)); + dbContextTypes.Add(typeof(TDbContext)); return this; } @@ -88,7 +87,7 @@ public IMongODMConfiguration AddDbContext( } public IMongODMConfiguration AddDbContext( - Action>? dbContextConfig = null) + Action? dbContextConfig = null) where TDbContext : class, IDbContext where TDbContextImpl : class, TDbContext { @@ -99,16 +98,14 @@ public IMongODMConfiguration AddDbContext( throw new InvalidOperationException("Configuration is frozen"); // Register dbContext. - RegisterSingleton(); - RegisterSingleton(sp => (TDbContextImpl)sp.GetService(typeof(TDbContext))); + services.AddSingleton(); // Register options. - var contextOptions = new DbContextOptions(); - dbContextConfig?.Invoke(contextOptions); - RegisterSingleton(contextOptions); + services.AddOptions(typeof(TDbContext).Name) + .Configure(dbContextConfig ?? (_ => { })); // Add db context type. - _dbContextTypes.Add(typeof(TDbContext)); + dbContextTypes.Add(typeof(TDbContext)); return this; } @@ -118,8 +115,11 @@ public IMongODMConfiguration AddDbContext( } } - public void Freeze() + public void Freeze(IMongODMOptionsBuilder mongODMOptionsBuilder) { + if (mongODMOptionsBuilder is null) + throw new ArgumentNullException(nameof(mongODMOptionsBuilder)); + configLock.EnterReadLock(); try { @@ -135,25 +135,14 @@ public void Freeze() { // Freeze. IsFrozen = true; + + // Report configuration to options. + mongODMOptionsBuilder.SetDbContextTypes(dbContextTypes); } finally { configLock.ExitWriteLock(); } } - - // Abstract protected methods. - protected abstract void RegisterSingleton() - where TService : class; - - protected abstract void RegisterSingleton(TService instance) - where TService : class; - - protected abstract void RegisterSingleton() - where TService : class - where TImplementation : class, TService; - - protected abstract void RegisterSingleton(Func implementationFactory) - where TService : class; } } diff --git a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs index d6e01c37..2acd08d8 100644 --- a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs +++ b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs @@ -14,8 +14,8 @@ using Etherna.ExecContext; using Etherna.ExecContext.AsyncLocal; -using Etherna.MongODM.AspNetCore; using Etherna.MongODM.Core; +using Etherna.MongODM.Core.Conventions; using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Options; using Etherna.MongODM.Core.ProxyModels; @@ -25,17 +25,21 @@ using Etherna.MongODM.Core.Tasks; using Etherna.MongODM.Core.Utility; using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; +using MongoDB.Bson; +using MongoDB.Bson.Serialization; +using MongoDB.Bson.Serialization.Conventions; using System; -namespace Microsoft.Extensions.DependencyInjection +namespace Etherna.MongODM.AspNetCore { public static class ServiceCollectionExtensions { public static IMongODMConfiguration AddMongODM( this IServiceCollection services, Action? configureOptions = null) - where TTaskRunner : class, ITaskRunner + where TTaskRunner : class, ITaskRunner, ITaskRunnerBuilder where TModelBase : class, IModel => //needed because of this https://jira.mongodb.org/browse/CSHARP-3154 AddMongODM(services, configureOptions); @@ -43,16 +47,33 @@ public static IMongODMConfiguration AddMongODM? configureOptions = null) where TProxyGenerator : class, IProxyGenerator - where TTaskRunner : class, ITaskRunner + where TTaskRunner : class, ITaskRunner, ITaskRunnerBuilder where TModelBase : class, IModel //needed because of this https://jira.mongodb.org/browse/CSHARP-3154 { // MongODM generic configuration. - var configuration = new AspNetCoreMongODMConfiguration(services); - services.TryAddSingleton(configuration); + var configuration = new MongODMConfiguration(services); - var mongODMOptions = new MongODMOptions(); - configureOptions?.Invoke(mongODMOptions); - services.TryAddSingleton(mongODMOptions); + services.AddOptions() + .Configure(configureOptions ?? (_ => { })) + .PostConfigure((options, proxyGenerator, taskRunner) => + { + // Register global conventions. + ConventionRegistry.Register("Enum string", new ConventionPack + { + new EnumRepresentationConvention(BsonType.String) + }, c => true); + + BsonSerializer.RegisterDiscriminatorConvention(typeof(TModelBase), + new HierarchicalProxyTolerantDiscriminatorConvention("_t", proxyGenerator)); + BsonSerializer.RegisterDiscriminatorConvention(typeof(EntityModelBase), + new HierarchicalProxyTolerantDiscriminatorConvention("_t", proxyGenerator)); + + // Freeze configuration into mongodm options. + configuration.Freeze(options); + + // Link options to services. + taskRunner.SetMongODMOptions(options); + }); services.TryAddSingleton(); @@ -64,6 +85,7 @@ public static IMongODMConfiguration AddMongODM(); services.TryAddSingleton(); + services.TryAddSingleton(); // DbContext internal. //dependencies @@ -87,9 +109,6 @@ public static IMongODMConfiguration AddMongODM(new Castle.DynamicProxy.ProxyGenerator()); - //static configurations - services.TryAddSingleton>(); - return configuration; } } diff --git a/src/MongODM.AspNetCore/StaticConfigurationBuilder.cs b/src/MongODM.AspNetCore/StaticConfigurationBuilder.cs deleted file mode 100644 index b008f1fe..00000000 --- a/src/MongODM.AspNetCore/StaticConfigurationBuilder.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright 2020-present Etherna Sagl -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using Etherna.MongODM.Core.Conventions; -using Etherna.MongODM.Core.Domain.Models; -using Etherna.MongODM.Core.ProxyModels; -using Etherna.MongODM.Core.Utility; -using MongoDB.Bson; -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Conventions; - -namespace Etherna.MongODM.AspNetCore -{ - public class StaticConfigurationBuilder : IStaticConfigurationBuilder - { - public StaticConfigurationBuilder(IProxyGenerator proxyGenerator) - { - // Register conventions. - ConventionRegistry.Register("Enum string", new ConventionPack - { - new EnumRepresentationConvention(BsonType.String) - }, c => true); - - BsonSerializer.RegisterDiscriminatorConvention(typeof(TModelBase), - new HierarchicalProxyTolerantDiscriminatorConvention("_t", proxyGenerator)); - BsonSerializer.RegisterDiscriminatorConvention(typeof(EntityModelBase), - new HierarchicalProxyTolerantDiscriminatorConvention("_t", proxyGenerator)); - } - } -} diff --git a/src/MongODM.Core/Options/DbContextOptions.cs b/src/MongODM.Core/Options/DbContextOptions.cs index d2abc7ea..eea5c139 100644 --- a/src/MongODM.Core/Options/DbContextOptions.cs +++ b/src/MongODM.Core/Options/DbContextOptions.cs @@ -12,28 +12,35 @@ // See the License for the specific language governing permissions and // limitations under the License. -using Etherna.MongODM.Core.Extensions; -using System.Linq; +using System; namespace Etherna.MongODM.Core.Options { public class DbContextOptions { - public string ConnectionString { get; set; } = "mongodb://localhost/localDb"; - public string DbName => ConnectionString.Split('?')[0] - .Split('/').Last(); + // Fields. + private string _connectionString = default!; + + // Properties. + public string ConnectionString + { + get + { + if (_connectionString is null) + _connectionString = $"mongodb://localhost/{DbName}"; + return _connectionString; + } + set + { + if (value is null) + throw new ArgumentNullException(nameof(ConnectionString)); + _connectionString = value; + } + } + public string DbName { get; set; } = "localDb"; public string DbOperationsCollectionName { get; set; } = "_db_ops"; public DocumentSemVerOptions DocumentSemVer { get; set; } = new DocumentSemVerOptions(); public string? Identifier { get; set; } public ModelMapVersionOptions ModelMapVersion { get; set; } = new ModelMapVersionOptions(); } - - public class DbContextOptions : DbContextOptions - where TDbContext : class, IDbContext - { - public DbContextOptions() - { - ConnectionString = $"mongodb://localhost/{typeof(TDbContext).Name.ToLowerFirstChar()}"; - } - } } diff --git a/src/MongODM.Core/Options/MongODMOptions.cs b/src/MongODM.Core/Options/MongODMOptions.cs index bd3fa50b..616b72c4 100644 --- a/src/MongODM.Core/Options/MongODMOptions.cs +++ b/src/MongODM.Core/Options/MongODMOptions.cs @@ -12,10 +12,19 @@ // See the License for the specific language governing permissions and // limitations under the License. +using System; +using System.Collections.Generic; + namespace Etherna.MongODM.Core.Options { - public class MongODMOptions + public sealed class MongODMOptions : IMongODMOptionsBuilder { + // Properties. + public IEnumerable DbContextTypes { get; private set; } = Array.Empty(); public string DbMaintenanceQueueName { get; set; } = "default"; + + // Explicit methods. + void IMongODMOptionsBuilder.SetDbContextTypes(IEnumerable dbContextTypes) => + DbContextTypes = dbContextTypes; } } diff --git a/src/MongODM.Core/Options/MongODMOptionsBuilder.cs b/src/MongODM.Core/Options/MongODMOptionsBuilder.cs new file mode 100644 index 00000000..91167983 --- /dev/null +++ b/src/MongODM.Core/Options/MongODMOptionsBuilder.cs @@ -0,0 +1,10 @@ +using System; +using System.Collections.Generic; + +namespace Etherna.MongODM.Core.Options +{ + public interface IMongODMOptionsBuilder + { + void SetDbContextTypes(IEnumerable dbContextTypes); + } +} diff --git a/src/MongODM.Core/Tasks/ITaskRunnerBuilder.cs b/src/MongODM.Core/Tasks/ITaskRunnerBuilder.cs new file mode 100644 index 00000000..a7d64bb6 --- /dev/null +++ b/src/MongODM.Core/Tasks/ITaskRunnerBuilder.cs @@ -0,0 +1,9 @@ +using Etherna.MongODM.Core.Options; + +namespace Etherna.MongODM.Core.Tasks +{ + public interface ITaskRunnerBuilder + { + void SetMongODMOptions(MongODMOptions options); + } +} diff --git a/src/MongODM.Core/Utility/IStaticConfigurationBuilder.cs b/src/MongODM.Core/Utility/IStaticConfigurationBuilder.cs deleted file mode 100644 index 6cb2fa50..00000000 --- a/src/MongODM.Core/Utility/IStaticConfigurationBuilder.cs +++ /dev/null @@ -1,26 +0,0 @@ -// Copyright 2020-present Etherna Sagl -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -namespace Etherna.MongODM.Core.Utility -{ - /// - /// This interface has the scope to inizialize only one time static configurations, when IoC system - /// has been configured, dependencies can be resolved, and before that any dbcontext starts to operate. - /// For a proper use, implements it in a class where configuration is invoked by constructor. - /// So configure it as a singleton on IoC system, and injectit as a dependency for DbContext. - /// - public interface IStaticConfigurationBuilder - { - } -} \ No newline at end of file diff --git a/src/MongODM.Hangfire/Tasks/HangfireTaskRunner.cs b/src/MongODM.Hangfire/Tasks/HangfireTaskRunner.cs index 8cfddb88..32ec2327 100644 --- a/src/MongODM.Hangfire/Tasks/HangfireTaskRunner.cs +++ b/src/MongODM.Hangfire/Tasks/HangfireTaskRunner.cs @@ -12,10 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -using Etherna.ExecContext.AsyncLocal; using Etherna.MongODM.Core.Options; using Etherna.MongODM.Core.Tasks; -using Etherna.MongODM.HF.Filters; using Hangfire; using Hangfire.States; using System; @@ -23,19 +21,17 @@ namespace Etherna.MongODM.HF.Tasks { - public class HangfireTaskRunner : ITaskRunner + public sealed class HangfireTaskRunner : ITaskRunner, ITaskRunnerBuilder { // Fields. private readonly IBackgroundJobClient backgroundJobClient; - private readonly MongODMOptions mongODMOptions; + private MongODMOptions mongODMOptions = default!; // Constructors. public HangfireTaskRunner( - IBackgroundJobClient backgroundJobClient, - MongODMOptions mongODMOptions) + IBackgroundJobClient backgroundJobClient) { this.backgroundJobClient = backgroundJobClient; - this.mongODMOptions = mongODMOptions; } // Methods. @@ -48,5 +44,9 @@ public void RunUpdateDocDependenciesTask(Type dbContextType, Type modelType, Typ backgroundJobClient.Create( task => task.RunAsync(dbContextType, modelType, keyType, idPaths, modelId), new EnqueuedState(mongODMOptions.DbMaintenanceQueueName)); + + // Explicit methods. + void ITaskRunnerBuilder.SetMongODMOptions(MongODMOptions options) => + mongODMOptions = options; } } diff --git a/src/MongODM/ServiceCollectionExtensions.cs b/src/MongODM/ServiceCollectionExtensions.cs index e55ba23b..413c3678 100644 --- a/src/MongODM/ServiceCollectionExtensions.cs +++ b/src/MongODM/ServiceCollectionExtensions.cs @@ -12,17 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. -using Etherna.MongODM; -using Etherna.MongODM.Core; +using Etherna.MongODM.AspNetCore; using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Options; using Etherna.MongODM.Core.ProxyModels; using Etherna.MongODM.HF.Tasks; using Hangfire; using Hangfire.Mongo; +using Microsoft.Extensions.DependencyInjection; using System; -namespace Microsoft.Extensions.DependencyInjection +namespace Etherna.MongODM { public static class ServiceCollectionExtensions { From 8ad41b0a0dc1c31448ce6f81efff75bb5dcb141a Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sun, 25 Jul 2021 18:23:37 +0200 Subject: [PATCH 11/78] Implemented automatic dbcontext seeding --- .../Persistence/SampleDbContext.cs | 8 --- .../MongODMConfiguration.cs | 49 +++++++----------- .../ServiceCollectionExtensions.cs | 5 +- src/MongODM.Core/DbContext.cs | 51 +++++++++++-------- .../Domain/ModelMaps/OperationBaseMap.cs | 2 +- src/MongODM.Core/IDbContext.cs | 9 ++-- src/MongODM.Core/IDbContextBuilder.cs | 10 ++++ src/MongODM.Core/Options/DbContextOptions.cs | 1 + .../Serialization/Mapping/ModelMap.cs | 4 +- .../Serialization/Mapping/SchemaRegister.cs | 2 +- .../Serializers/ReferenceSerializer.cs | 6 +-- .../ReferenceSerializerConfiguration.cs | 2 +- 12 files changed, 77 insertions(+), 72 deletions(-) create mode 100644 src/MongODM.Core/IDbContextBuilder.cs diff --git a/samples/AspNetCoreSample/Persistence/SampleDbContext.cs b/samples/AspNetCoreSample/Persistence/SampleDbContext.cs index 98c2c1e1..0bbc0d62 100644 --- a/samples/AspNetCoreSample/Persistence/SampleDbContext.cs +++ b/samples/AspNetCoreSample/Persistence/SampleDbContext.cs @@ -15,22 +15,14 @@ using Etherna.MongODM.AspNetCoreSample.Models; using Etherna.MongODM.AspNetCoreSample.Models.ModelMaps; using Etherna.MongODM.Core; -using Etherna.MongODM.Core.Options; using Etherna.MongODM.Core.Repositories; using Etherna.MongODM.Core.Serialization; -using Microsoft.Extensions.Options; using System.Collections.Generic; namespace Etherna.MongODM.AspNetCoreSample.Persistence { public class SampleDbContext : DbContext, ISampleDbContext { - public SampleDbContext( - IDbDependencies dependencies, - IOptionsMonitor options) - : base(dependencies, options.Get(nameof(ISampleDbContext))) - { } - public ICollectionRepository Cats { get; } = new CollectionRepository("cats"); protected override IEnumerable ModelMapsCollectors => diff --git a/src/MongODM.AspNetCore/MongODMConfiguration.cs b/src/MongODM.AspNetCore/MongODMConfiguration.cs index d5f21575..52e14b70 100644 --- a/src/MongODM.AspNetCore/MongODMConfiguration.cs +++ b/src/MongODM.AspNetCore/MongODMConfiguration.cs @@ -60,31 +60,8 @@ protected virtual void Dispose(bool disposing) // Methods. public IMongODMConfiguration AddDbContext( Action? dbContextConfig = null) - where TDbContext : class, IDbContext - { - configLock.EnterWriteLock(); - try - { - if (IsFrozen) - throw new InvalidOperationException("Configuration is frozen"); - - // Register dbContext. - services.AddSingleton(); - - // Register options. - services.AddOptions(typeof(TDbContext).Name) - .Configure(dbContextConfig ?? (_ => { })); - - // Add db context type. - dbContextTypes.Add(typeof(TDbContext)); - - return this; - } - finally - { - configLock.ExitWriteLock(); - } - } + where TDbContext : class, IDbContext => + AddDbContext(dbContextConfig); public IMongODMConfiguration AddDbContext( Action? dbContextConfig = null) @@ -98,11 +75,23 @@ public IMongODMConfiguration AddDbContext( throw new InvalidOperationException("Configuration is frozen"); // Register dbContext. - services.AddSingleton(); - - // Register options. - services.AddOptions(typeof(TDbContext).Name) - .Configure(dbContextConfig ?? (_ => { })); + services.AddSingleton(sp => + { + // Get dependencies. + var dependencies = sp.GetRequiredService(); + var options = new DbContextOptions(); + dbContextConfig?.Invoke(options); + + // Initialize instance. + var dbContext = Activator.CreateInstance(); + if (dbContext is not IDbContextBuilder dbContextBuilder) + throw new InvalidOperationException($"DbContext doesn't implement {nameof(IDbContextBuilder)}"); + + var task = dbContextBuilder.InitializeAsync(dependencies, options); + task.Wait(); + + return dbContext; + }); // Add db context type. dbContextTypes.Add(typeof(TDbContext)); diff --git a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs index 2acd08d8..00b85aaf 100644 --- a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs +++ b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs @@ -55,7 +55,8 @@ public static IMongODMConfiguration AddMongODM() .Configure(configureOptions ?? (_ => { })) - .PostConfigure((options, proxyGenerator, taskRunner) => + .PostConfigure( + (options, proxyGenerator, taskRunnerBuilder) => { // Register global conventions. ConventionRegistry.Register("Enum string", new ConventionPack @@ -72,7 +73,7 @@ public static IMongODMConfiguration AddMongODM(); diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index a4f949f1..8671dcce 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -33,31 +33,36 @@ namespace Etherna.MongODM.Core { - public abstract class DbContext : IDbContext + public abstract class DbContext : IDbContext, IDbContextBuilder { - // Constructors and initialization. - protected DbContext( + // Fields. + private bool isInitialized; + + // Constructor and initializer. + protected DbContext() { } + public async Task InitializeAsync( IDbDependencies dependencies, DbContextOptions options) { + if (isInitialized) + throw new InvalidOperationException("DbContext already initialized"); if (dependencies is null) throw new ArgumentNullException(nameof(dependencies)); if (options is null) throw new ArgumentNullException(nameof(options)); + // Set dependencies. DbCache = dependencies.DbCache; DbMaintainer = dependencies.DbMaintainer; DbMigrationManager = dependencies.DbMigrationManager; DbOperations = new CollectionRepository(options.DbOperationsCollectionName); - DocumentSemVerOptions = options.DocumentSemVer; - Identifier = options.Identifier ?? GetType().Name; LibraryVersion = typeof(DbContext) .GetTypeInfo() .Assembly .GetCustomAttribute() ?.InformationalVersion ?.Split('+')[0] ?? "1.0.0"; - ModelMapVersionOptions = options.ModelMapVersion; + Options = options; ProxyGenerator = dependencies.ProxyGenerator; RepositoryRegister = dependencies.RepositoryRegister; SchemaRegister = dependencies.SchemaRegister; @@ -90,6 +95,13 @@ protected DbContext( // Build and freeze schemas register. SchemaRegister.Freeze(); + + // Initialize data. + if (!Options.DisableAutomaticSeed) + await SeedIfNeededAsync().ConfigureAwait(false); + + // Set as initialized. + isInitialized = true; } // Public properties. @@ -97,21 +109,20 @@ protected DbContext( DbCache.LoadedModels.Values .Where(model => (model as IAuditable)?.IsChanged == true) .ToList(); - public IMongoClient Client { get; } - public IMongoDatabase Database { get; } - public IDbCache DbCache { get; } - public IDbMaintainer DbMaintainer { get; } - public IDbMigrationManager DbMigrationManager { get; } - public ICollectionRepository DbOperations { get; } + public IMongoClient Client { get; private set; } = default!; + public IMongoDatabase Database { get; private set; } = default!; + public IDbCache DbCache { get; private set; } = default!; + public IDbMaintainer DbMaintainer { get; private set; } = default!; + public IDbMigrationManager DbMigrationManager { get; private set; } = default!; + public ICollectionRepository DbOperations { get; private set; } = default!; public virtual IEnumerable DocumentMigrationList { get; } = Array.Empty(); - public DocumentSemVerOptions DocumentSemVerOptions { get; } - public string Identifier { get; } - public SemanticVersion LibraryVersion { get; } - public ModelMapVersionOptions ModelMapVersionOptions { get; } - public IProxyGenerator ProxyGenerator { get; } - public IRepositoryRegister RepositoryRegister { get; } - public ISchemaRegister SchemaRegister { get; } - public ISerializerModifierAccessor SerializerModifierAccessor { get; } + public string Identifier => Options?.Identifier ?? GetType().Name; + public SemanticVersion LibraryVersion { get; private set; } = default!; + public DbContextOptions Options { get; private set; } = default!; + public IProxyGenerator ProxyGenerator { get; private set; } = default!; + public IRepositoryRegister RepositoryRegister { get; private set; } = default!; + public ISchemaRegister SchemaRegister { get; private set; } = default!; + public ISerializerModifierAccessor SerializerModifierAccessor { get; private set; } = default!; // Protected properties. protected abstract IEnumerable ModelMapsCollectors { get; } diff --git a/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs b/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs index 6498edcd..d2e8904e 100644 --- a/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs +++ b/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs @@ -31,7 +31,7 @@ public void Register(IDbContext dbContext) CurrentVersion = dbContext.LibraryVersion, WriteInDocuments = false }, - dbContext.ModelMapVersionOptions, + dbContext.Options.ModelMapVersion, dbContext.SchemaRegister, dbContext.SerializerModifierAccessor)); } diff --git a/src/MongODM.Core/IDbContext.cs b/src/MongODM.Core/IDbContext.cs index 6f8b240c..6cd98144 100644 --- a/src/MongODM.Core/IDbContext.cs +++ b/src/MongODM.Core/IDbContext.cs @@ -69,19 +69,20 @@ public interface IDbContext /// IEnumerable DocumentMigrationList { get; } - DocumentSemVerOptions DocumentSemVerOptions { get; } - /// /// DbContext unique identifier. /// string Identifier { get; } /// - /// Current MongODM library version + /// Current MongODM library version. /// SemanticVersion LibraryVersion { get; } - ModelMapVersionOptions ModelMapVersionOptions { get; } + /// + /// Db context options. + /// + DbContextOptions Options { get; } /// /// Current model proxy generator. diff --git a/src/MongODM.Core/IDbContextBuilder.cs b/src/MongODM.Core/IDbContextBuilder.cs new file mode 100644 index 00000000..badac488 --- /dev/null +++ b/src/MongODM.Core/IDbContextBuilder.cs @@ -0,0 +1,10 @@ +using Etherna.MongODM.Core.Options; +using System.Threading.Tasks; + +namespace Etherna.MongODM.Core +{ + public interface IDbContextBuilder + { + Task InitializeAsync(IDbDependencies dependencies, DbContextOptions options); + } +} diff --git a/src/MongODM.Core/Options/DbContextOptions.cs b/src/MongODM.Core/Options/DbContextOptions.cs index eea5c139..06ea27c8 100644 --- a/src/MongODM.Core/Options/DbContextOptions.cs +++ b/src/MongODM.Core/Options/DbContextOptions.cs @@ -39,6 +39,7 @@ public string ConnectionString } public string DbName { get; set; } = "localDb"; public string DbOperationsCollectionName { get; set; } = "_db_ops"; + public bool DisableAutomaticSeed { get; set; } public DocumentSemVerOptions DocumentSemVer { get; set; } = new DocumentSemVerOptions(); public string? Identifier { get; set; } public ModelMapVersionOptions ModelMapVersion { get; set; } = new ModelMapVersionOptions(); diff --git a/src/MongODM.Core/Serialization/Mapping/ModelMap.cs b/src/MongODM.Core/Serialization/Mapping/ModelMap.cs index e6a612be..4dab9ff8 100644 --- a/src/MongODM.Core/Serialization/Mapping/ModelMap.cs +++ b/src/MongODM.Core/Serialization/Mapping/ModelMap.cs @@ -101,8 +101,8 @@ public static IBsonSerializer GetDefaultSerializer(IDbContext db return new ModelMapSerializer( dbContext.DbCache, - dbContext.DocumentSemVerOptions, - dbContext.ModelMapVersionOptions, + dbContext.Options.DocumentSemVer, + dbContext.Options.ModelMapVersion, dbContext.SchemaRegister, dbContext.SerializerModifierAccessor); } diff --git a/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs b/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs index 52eebeb4..b1aeb657 100644 --- a/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs @@ -235,7 +235,7 @@ protected override void FreezeAction() activeModelMapIdBsonElement.Add( schema.ModelType, new BsonElement( - dbContext.ModelMapVersionOptions.ElementName, + dbContext.Options.ModelMapVersion.ElementName, new BsonString(notProxySchema.ActiveMap.Id))); } } diff --git a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs index dd993c27..f1d60732 100644 --- a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs @@ -126,7 +126,7 @@ public override TModelBase Deserialize(BsonDeserializationContext context, BsonD //get model map id string? modelMapId = null; - if (bsonDocument.TryGetElement(dbContext.ModelMapVersionOptions.ElementName, out BsonElement modelMapIdElement)) + if (bsonDocument.TryGetElement(dbContext.Options.ModelMapVersion.ElementName, out BsonElement modelMapIdElement)) { modelMapId = BsonValueToModelMapId(modelMapIdElement.Value); bsonDocument.RemoveElement(modelMapIdElement); //don't report into extra elements @@ -290,8 +290,8 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati // Add additional data. //add model map id - if (bsonDocument.Contains(dbContext.ModelMapVersionOptions.ElementName)) - bsonDocument.Remove(dbContext.ModelMapVersionOptions.ElementName); + if (bsonDocument.Contains(dbContext.Options.ModelMapVersion.ElementName)) + bsonDocument.Remove(dbContext.Options.ModelMapVersion.ElementName); var modelMapIdElement = configuration.GetActiveModelMapIdBsonElement( dbContext.ProxyGenerator.PurgeProxyType(value.GetType())); bsonDocument.InsertAt(0, modelMapIdElement); diff --git a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerConfiguration.cs b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerConfiguration.cs index d62fb096..7604f388 100644 --- a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerConfiguration.cs +++ b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerConfiguration.cs @@ -137,7 +137,7 @@ protected override void FreezeAction() activeModelMapIdBsonElement.Add( schema.ModelType, new BsonElement( - dbContext.ModelMapVersionOptions.ElementName, + dbContext.Options.ModelMapVersion.ElementName, new BsonString(notProxySchema.ActiveMap.Id))); } } From e1eb2ebdedc024dea1da816f8350bf0f34fb4788 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sun, 25 Jul 2021 18:32:03 +0200 Subject: [PATCH 12/78] Exposing readonly IDbContextOptions from dbcontext --- src/MongODM.Core/DbContext.cs | 4 +-- src/MongODM.Core/IDbContext.cs | 2 +- src/MongODM.Core/IDbContextBuilder.cs | 2 +- src/MongODM.Core/Options/DbContextOptions.cs | 2 +- src/MongODM.Core/Options/IDbContextOptions.cs | 27 +++++++++++++++++++ 5 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 src/MongODM.Core/Options/IDbContextOptions.cs diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index 8671dcce..d0d35409 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -42,7 +42,7 @@ public abstract class DbContext : IDbContext, IDbContextBuilder protected DbContext() { } public async Task InitializeAsync( IDbDependencies dependencies, - DbContextOptions options) + IDbContextOptions options) { if (isInitialized) throw new InvalidOperationException("DbContext already initialized"); @@ -118,7 +118,7 @@ public async Task InitializeAsync( public virtual IEnumerable DocumentMigrationList { get; } = Array.Empty(); public string Identifier => Options?.Identifier ?? GetType().Name; public SemanticVersion LibraryVersion { get; private set; } = default!; - public DbContextOptions Options { get; private set; } = default!; + public IDbContextOptions Options { get; private set; } = default!; public IProxyGenerator ProxyGenerator { get; private set; } = default!; public IRepositoryRegister RepositoryRegister { get; private set; } = default!; public ISchemaRegister SchemaRegister { get; private set; } = default!; diff --git a/src/MongODM.Core/IDbContext.cs b/src/MongODM.Core/IDbContext.cs index 6cd98144..0c179b1b 100644 --- a/src/MongODM.Core/IDbContext.cs +++ b/src/MongODM.Core/IDbContext.cs @@ -82,7 +82,7 @@ public interface IDbContext /// /// Db context options. /// - DbContextOptions Options { get; } + IDbContextOptions Options { get; } /// /// Current model proxy generator. diff --git a/src/MongODM.Core/IDbContextBuilder.cs b/src/MongODM.Core/IDbContextBuilder.cs index badac488..3b23e1f6 100644 --- a/src/MongODM.Core/IDbContextBuilder.cs +++ b/src/MongODM.Core/IDbContextBuilder.cs @@ -5,6 +5,6 @@ namespace Etherna.MongODM.Core { public interface IDbContextBuilder { - Task InitializeAsync(IDbDependencies dependencies, DbContextOptions options); + Task InitializeAsync(IDbDependencies dependencies, IDbContextOptions options); } } diff --git a/src/MongODM.Core/Options/DbContextOptions.cs b/src/MongODM.Core/Options/DbContextOptions.cs index 06ea27c8..8be83635 100644 --- a/src/MongODM.Core/Options/DbContextOptions.cs +++ b/src/MongODM.Core/Options/DbContextOptions.cs @@ -16,7 +16,7 @@ namespace Etherna.MongODM.Core.Options { - public class DbContextOptions + public class DbContextOptions : IDbContextOptions { // Fields. private string _connectionString = default!; diff --git a/src/MongODM.Core/Options/IDbContextOptions.cs b/src/MongODM.Core/Options/IDbContextOptions.cs new file mode 100644 index 00000000..0248dd44 --- /dev/null +++ b/src/MongODM.Core/Options/IDbContextOptions.cs @@ -0,0 +1,27 @@ +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Etherna.MongODM.Core.Options +{ + public interface IDbContextOptions + { + public string ConnectionString { get; } + public string DbName { get; } + public string DbOperationsCollectionName { get; } + public bool DisableAutomaticSeed { get; } + public DocumentSemVerOptions DocumentSemVer { get; } + public string? Identifier { get; } + public ModelMapVersionOptions ModelMapVersion { get; } + } +} \ No newline at end of file From 9bb986ad63c9f232d2740e04fd5f1771c4d16d0c Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sun, 25 Jul 2021 19:12:14 +0200 Subject: [PATCH 13/78] Implemented AddDbContext passing dbcontext instance --- .../IMongODMConfiguration.cs | 19 ++++++++--- .../MongODMConfiguration.cs | 33 ++++++++++++------- 2 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/MongODM.AspNetCore/IMongODMConfiguration.cs b/src/MongODM.AspNetCore/IMongODMConfiguration.cs index 15e778fd..ee9fa678 100644 --- a/src/MongODM.AspNetCore/IMongODMConfiguration.cs +++ b/src/MongODM.AspNetCore/IMongODMConfiguration.cs @@ -24,13 +24,24 @@ public interface IMongODMConfiguration // Methods. IMongODMConfiguration AddDbContext( - Action? dbContextConfig = null) - where TDbContext : class, IDbContext; + Action? dbContextOptionsConfig = null) + where TDbContext : DbContext, new(); + + IMongODMConfiguration AddDbContext( + TDbContext dbContext, + Action? dbContextOptionsConfig = null) + where TDbContext : DbContext; + + IMongODMConfiguration AddDbContext( + Action? dbContextOptionsConfig = null) + where TDbContext : class, IDbContext + where TDbContextImpl : DbContext, TDbContext, new(); IMongODMConfiguration AddDbContext( - Action? dbContextConfig = null) + TDbContextImpl dbContext, + Action? dbContextOptionsConfig = null) where TDbContext : class, IDbContext - where TDbContextImpl : class, TDbContext; + where TDbContextImpl : DbContext, TDbContext; /// /// Freeze configuration. diff --git a/src/MongODM.AspNetCore/MongODMConfiguration.cs b/src/MongODM.AspNetCore/MongODMConfiguration.cs index 52e14b70..4cafe7c7 100644 --- a/src/MongODM.AspNetCore/MongODMConfiguration.cs +++ b/src/MongODM.AspNetCore/MongODMConfiguration.cs @@ -59,14 +59,29 @@ protected virtual void Dispose(bool disposing) // Methods. public IMongODMConfiguration AddDbContext( - Action? dbContextConfig = null) - where TDbContext : class, IDbContext => - AddDbContext(dbContextConfig); + Action? dbContextOptionsConfig = null) + where TDbContext : DbContext, new() => + AddDbContext(dbContextOptionsConfig); + + public IMongODMConfiguration AddDbContext( + TDbContext dbContext, + Action? dbContextOptionsConfig = null) + where TDbContext : DbContext => + AddDbContext(dbContext, dbContextOptionsConfig); + + public IMongODMConfiguration AddDbContext( + Action? dbContextOptionsConfig = null) + where TDbContext : class, IDbContext + where TDbContextImpl : DbContext, TDbContext, new() => + AddDbContext( + Activator.CreateInstance(), + dbContextOptionsConfig); public IMongODMConfiguration AddDbContext( - Action? dbContextConfig = null) + TDbContextImpl dbContext, + Action? dbContextOptionsConfig = null) where TDbContext : class, IDbContext - where TDbContextImpl : class, TDbContext + where TDbContextImpl : DbContext, TDbContext { configLock.EnterWriteLock(); try @@ -80,14 +95,10 @@ public IMongODMConfiguration AddDbContext( // Get dependencies. var dependencies = sp.GetRequiredService(); var options = new DbContextOptions(); - dbContextConfig?.Invoke(options); + dbContextOptionsConfig?.Invoke(options); // Initialize instance. - var dbContext = Activator.CreateInstance(); - if (dbContext is not IDbContextBuilder dbContextBuilder) - throw new InvalidOperationException($"DbContext doesn't implement {nameof(IDbContextBuilder)}"); - - var task = dbContextBuilder.InitializeAsync(dependencies, options); + var task = dbContext.InitializeAsync(dependencies, options); task.Wait(); return dbContext; From 5027e9a73eba6dcc1e62a7ca110b60c89d1f41bb Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Mon, 26 Jul 2021 01:59:32 +0200 Subject: [PATCH 14/78] Added function for create dbcontext with service provider --- .../IMongODMConfiguration.cs | 11 ++++++++++ .../MongODMConfiguration.cs | 20 +++++++++++++++++-- 2 files changed, 29 insertions(+), 2 deletions(-) diff --git a/src/MongODM.AspNetCore/IMongODMConfiguration.cs b/src/MongODM.AspNetCore/IMongODMConfiguration.cs index ee9fa678..888951be 100644 --- a/src/MongODM.AspNetCore/IMongODMConfiguration.cs +++ b/src/MongODM.AspNetCore/IMongODMConfiguration.cs @@ -32,6 +32,11 @@ IMongODMConfiguration AddDbContext( Action? dbContextOptionsConfig = null) where TDbContext : DbContext; + IMongODMConfiguration AddDbContext( + Func dbContextCreator, + Action? dbContextOptionsConfig = null) + where TDbContext : DbContext; + IMongODMConfiguration AddDbContext( Action? dbContextOptionsConfig = null) where TDbContext : class, IDbContext @@ -43,6 +48,12 @@ IMongODMConfiguration AddDbContext( where TDbContext : class, IDbContext where TDbContextImpl : DbContext, TDbContext; + IMongODMConfiguration AddDbContext( + Func dbContextCreator, + Action? dbContextOptionsConfig = null) + where TDbContext : class, IDbContext + where TDbContextImpl : DbContext, TDbContext; + /// /// Freeze configuration. /// diff --git a/src/MongODM.AspNetCore/MongODMConfiguration.cs b/src/MongODM.AspNetCore/MongODMConfiguration.cs index 4cafe7c7..8fcc22d5 100644 --- a/src/MongODM.AspNetCore/MongODMConfiguration.cs +++ b/src/MongODM.AspNetCore/MongODMConfiguration.cs @@ -67,20 +67,33 @@ public IMongODMConfiguration AddDbContext( TDbContext dbContext, Action? dbContextOptionsConfig = null) where TDbContext : DbContext => - AddDbContext(dbContext, dbContextOptionsConfig); + AddDbContext(_ => dbContext, dbContextOptionsConfig); + + public IMongODMConfiguration AddDbContext( + Func dbContextCreator, + Action? dbContextOptionsConfig = null) + where TDbContext : DbContext => + AddDbContext(dbContextCreator, dbContextOptionsConfig); public IMongODMConfiguration AddDbContext( Action? dbContextOptionsConfig = null) where TDbContext : class, IDbContext where TDbContextImpl : DbContext, TDbContext, new() => AddDbContext( - Activator.CreateInstance(), + _ => Activator.CreateInstance(), dbContextOptionsConfig); public IMongODMConfiguration AddDbContext( TDbContextImpl dbContext, Action? dbContextOptionsConfig = null) where TDbContext : class, IDbContext + where TDbContextImpl : DbContext, TDbContext => + AddDbContext(_ => dbContext, dbContextOptionsConfig); + + public IMongODMConfiguration AddDbContext( + Func dbContextCreator, + Action? dbContextOptionsConfig) + where TDbContext : class, IDbContext where TDbContextImpl : DbContext, TDbContext { configLock.EnterWriteLock(); @@ -97,6 +110,9 @@ public IMongODMConfiguration AddDbContext( var options = new DbContextOptions(); dbContextOptionsConfig?.Invoke(options); + // Get dbcontext. + var dbContext = dbContextCreator(sp); + // Initialize instance. var task = dbContext.InitializeAsync(dependencies, options); task.Wait(); From f81fb9e1f4718132cd75407a96c1f7b4688ccbb1 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Mon, 26 Jul 2021 17:06:18 +0200 Subject: [PATCH 15/78] Fixed an issue with DbContextOptions.DbName --- src/MongODM.Core/Options/DbContextOptions.cs | 24 ++++---------------- 1 file changed, 4 insertions(+), 20 deletions(-) diff --git a/src/MongODM.Core/Options/DbContextOptions.cs b/src/MongODM.Core/Options/DbContextOptions.cs index 8be83635..0c8e0182 100644 --- a/src/MongODM.Core/Options/DbContextOptions.cs +++ b/src/MongODM.Core/Options/DbContextOptions.cs @@ -12,32 +12,16 @@ // See the License for the specific language governing permissions and // limitations under the License. -using System; +using System.Linq; namespace Etherna.MongODM.Core.Options { public class DbContextOptions : IDbContextOptions { - // Fields. - private string _connectionString = default!; - // Properties. - public string ConnectionString - { - get - { - if (_connectionString is null) - _connectionString = $"mongodb://localhost/{DbName}"; - return _connectionString; - } - set - { - if (value is null) - throw new ArgumentNullException(nameof(ConnectionString)); - _connectionString = value; - } - } - public string DbName { get; set; } = "localDb"; + public string ConnectionString { get; set; } = "mongodb://localhost/localDb"; + public string DbName => ConnectionString.Split('?')[0] + .Split('/').Last(); public string DbOperationsCollectionName { get; set; } = "_db_ops"; public bool DisableAutomaticSeed { get; set; } public DocumentSemVerOptions DocumentSemVer { get; set; } = new DocumentSemVerOptions(); From 3577e7e731a653c82abc5e1ea6606dfb244e8121 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Mon, 26 Jul 2021 22:37:12 +0200 Subject: [PATCH 16/78] Exported the ExecutionContext project --- MongODM.sln | 14 --- .../AsyncLocal/AsyncLocalContext.cs | 56 ----------- .../AsyncLocal/AsyncLocalContextHandler.cs | 35 ------- .../AsyncLocal/IAsyncLocalContext.cs | 32 ------- .../AsyncLocal/IAsyncLocalContextHandler.cs | 25 ----- .../AsyncLocal/IHandledAsyncLocalContext.cs | 25 ----- .../ExecutionContextNotFoundException.cs | 30 ------ src/ExecutionContext/ExecutionContext.csproj | 42 --------- .../ExecutionContextSelector.cs | 54 ----------- src/ExecutionContext/GlobalSuppressions.cs | 22 ----- src/ExecutionContext/IExecutionContext.cs | 30 ------ .../Properties/AssemblyInfo.cs | 20 ---- .../MongODM.AspNetCore.csproj | 1 + .../ServiceCollectionExtensions.cs | 12 +-- src/MongODM.Core/MongODM.Core.csproj | 5 +- .../AsyncLocalContextHandlerTests.cs | 48 ---------- .../AsyncLocal/AsyncLocalContextTests.cs | 93 ------------------- .../ExecutionContext.Tests.csproj | 25 ----- .../ExecutionContextSelectorTests.cs | 50 ---------- 19 files changed, 4 insertions(+), 615 deletions(-) delete mode 100644 src/ExecutionContext/AsyncLocal/AsyncLocalContext.cs delete mode 100644 src/ExecutionContext/AsyncLocal/AsyncLocalContextHandler.cs delete mode 100644 src/ExecutionContext/AsyncLocal/IAsyncLocalContext.cs delete mode 100644 src/ExecutionContext/AsyncLocal/IAsyncLocalContextHandler.cs delete mode 100644 src/ExecutionContext/AsyncLocal/IHandledAsyncLocalContext.cs delete mode 100644 src/ExecutionContext/Exceptions/ExecutionContextNotFoundException.cs delete mode 100644 src/ExecutionContext/ExecutionContext.csproj delete mode 100644 src/ExecutionContext/ExecutionContextSelector.cs delete mode 100644 src/ExecutionContext/GlobalSuppressions.cs delete mode 100644 src/ExecutionContext/IExecutionContext.cs delete mode 100644 src/ExecutionContext/Properties/AssemblyInfo.cs delete mode 100644 test/ExecutionContext.Tests/AsyncLocal/AsyncLocalContextHandlerTests.cs delete mode 100644 test/ExecutionContext.Tests/AsyncLocal/AsyncLocalContextTests.cs delete mode 100644 test/ExecutionContext.Tests/ExecutionContext.Tests.csproj delete mode 100644 test/ExecutionContext.Tests/ExecutionContextSelectorTests.cs diff --git a/MongODM.sln b/MongODM.sln index c2956af9..9549975c 100644 --- a/MongODM.sln +++ b/MongODM.sln @@ -9,10 +9,6 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{CF1ABDEA-7 EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MongODM.Hangfire", "src\MongODM.Hangfire\MongODM.Hangfire.csproj", "{10897D0D-4898-4A4D-8D1E-B2435E93D9A1}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExecutionContext", "src\ExecutionContext\ExecutionContext.csproj", "{DB6C020D-1C93-4456-8FB5-EF7CF505DF7B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ExecutionContext.Tests", "test\ExecutionContext.Tests\ExecutionContext.Tests.csproj", "{BF4F963A-DBCE-4C53-A209-502F4CAF12C5}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MongODM.AspNetCore", "src\MongODM.AspNetCore\MongODM.AspNetCore.csproj", "{6374F645-5D17-494E-9529-7F83426900B3}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MongODM.Core", "src\MongODM.Core\MongODM.Core.csproj", "{4F2498A9-D60D-4D49-95B9-BC78EE2917B5}" @@ -52,14 +48,6 @@ Global {10897D0D-4898-4A4D-8D1E-B2435E93D9A1}.Debug|Any CPU.Build.0 = Debug|Any CPU {10897D0D-4898-4A4D-8D1E-B2435E93D9A1}.Release|Any CPU.ActiveCfg = Release|Any CPU {10897D0D-4898-4A4D-8D1E-B2435E93D9A1}.Release|Any CPU.Build.0 = Release|Any CPU - {DB6C020D-1C93-4456-8FB5-EF7CF505DF7B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {DB6C020D-1C93-4456-8FB5-EF7CF505DF7B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {DB6C020D-1C93-4456-8FB5-EF7CF505DF7B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {DB6C020D-1C93-4456-8FB5-EF7CF505DF7B}.Release|Any CPU.Build.0 = Release|Any CPU - {BF4F963A-DBCE-4C53-A209-502F4CAF12C5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BF4F963A-DBCE-4C53-A209-502F4CAF12C5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {BF4F963A-DBCE-4C53-A209-502F4CAF12C5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BF4F963A-DBCE-4C53-A209-502F4CAF12C5}.Release|Any CPU.Build.0 = Release|Any CPU {6374F645-5D17-494E-9529-7F83426900B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {6374F645-5D17-494E-9529-7F83426900B3}.Debug|Any CPU.Build.0 = Debug|Any CPU {6374F645-5D17-494E-9529-7F83426900B3}.Release|Any CPU.ActiveCfg = Release|Any CPU @@ -90,8 +78,6 @@ Global EndGlobalSection GlobalSection(NestedProjects) = preSolution {10897D0D-4898-4A4D-8D1E-B2435E93D9A1} = {490DAED7-DAD8-459A-A20E-F57F2F6F619E} - {DB6C020D-1C93-4456-8FB5-EF7CF505DF7B} = {490DAED7-DAD8-459A-A20E-F57F2F6F619E} - {BF4F963A-DBCE-4C53-A209-502F4CAF12C5} = {CF1ABDEA-794F-4474-858D-BCB61F367D72} {6374F645-5D17-494E-9529-7F83426900B3} = {490DAED7-DAD8-459A-A20E-F57F2F6F619E} {4F2498A9-D60D-4D49-95B9-BC78EE2917B5} = {490DAED7-DAD8-459A-A20E-F57F2F6F619E} {50D6BEE5-54B5-43F3-BA92-6107AB6E311E} = {CF1ABDEA-794F-4474-858D-BCB61F367D72} diff --git a/src/ExecutionContext/AsyncLocal/AsyncLocalContext.cs b/src/ExecutionContext/AsyncLocal/AsyncLocalContext.cs deleted file mode 100644 index 38b59568..00000000 --- a/src/ExecutionContext/AsyncLocal/AsyncLocalContext.cs +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright 2020-present Etherna Sagl -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System; -using System.Collections.Generic; -using System.Threading; - -namespace Etherna.ExecContext.AsyncLocal -{ - /// - /// Async local context implementation. This can be used as singleton or with multiple instances. - /// The container permits to have an Item instance inside this - /// method calling tree. - /// - /// - /// Before try to use an async local context, call the method - /// for initialize the container, and receive a context handler. - /// After have used, dispose the handler for destroy the current context dictionary. - /// - public class AsyncLocalContext : IAsyncLocalContext, IHandledAsyncLocalContext - { - // Fields. - private static readonly AsyncLocal?> asyncLocalContext = new(); - - // Properties. - public IDictionary? Items => asyncLocalContext.Value; - - // Static properties. - public static IAsyncLocalContext Instance { get; } = new AsyncLocalContext(); - - // Methods. - public IAsyncLocalContextHandler InitAsyncLocalContext() - { - if (asyncLocalContext.Value != null) - throw new InvalidOperationException("Only one context at time is supported"); - - asyncLocalContext.Value = new Dictionary(); - - return new AsyncLocalContextHandler(this); - } - - public void OnDisposed(IAsyncLocalContextHandler context) => - asyncLocalContext.Value = null; - } -} diff --git a/src/ExecutionContext/AsyncLocal/AsyncLocalContextHandler.cs b/src/ExecutionContext/AsyncLocal/AsyncLocalContextHandler.cs deleted file mode 100644 index 4f9325e8..00000000 --- a/src/ExecutionContext/AsyncLocal/AsyncLocalContextHandler.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020-present Etherna Sagl -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -namespace Etherna.ExecContext.AsyncLocal -{ - /// - /// The handler for an initialization. - /// Dispose this for release the context. - /// - public sealed class AsyncLocalContextHandler : IAsyncLocalContextHandler - { - // Constructors. - internal AsyncLocalContextHandler(IHandledAsyncLocalContext handledContext) - { - HandledContext = handledContext; - } - - // Properties. - internal IHandledAsyncLocalContext HandledContext { get; } - - // Methods. - public void Dispose() => HandledContext.OnDisposed(this); - } -} diff --git a/src/ExecutionContext/AsyncLocal/IAsyncLocalContext.cs b/src/ExecutionContext/AsyncLocal/IAsyncLocalContext.cs deleted file mode 100644 index 1695d3ec..00000000 --- a/src/ExecutionContext/AsyncLocal/IAsyncLocalContext.cs +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright 2020-present Etherna Sagl -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System; - -namespace Etherna.ExecContext.AsyncLocal -{ - /// - /// The interface. - /// Permits to create an async local context living with the method calling tree. - /// - public interface IAsyncLocalContext : IExecutionContext - { - /// - /// Initialize a new async local context - /// - /// The new context handler - /// Throw when another local context is found - IAsyncLocalContextHandler InitAsyncLocalContext(); - } -} \ No newline at end of file diff --git a/src/ExecutionContext/AsyncLocal/IAsyncLocalContextHandler.cs b/src/ExecutionContext/AsyncLocal/IAsyncLocalContextHandler.cs deleted file mode 100644 index 51f1885c..00000000 --- a/src/ExecutionContext/AsyncLocal/IAsyncLocalContextHandler.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2020-present Etherna Sagl -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System; - -namespace Etherna.ExecContext.AsyncLocal -{ - /// - /// A disposable interface for - /// - public interface IAsyncLocalContextHandler : IDisposable - { - } -} diff --git a/src/ExecutionContext/AsyncLocal/IHandledAsyncLocalContext.cs b/src/ExecutionContext/AsyncLocal/IHandledAsyncLocalContext.cs deleted file mode 100644 index 6236049c..00000000 --- a/src/ExecutionContext/AsyncLocal/IHandledAsyncLocalContext.cs +++ /dev/null @@ -1,25 +0,0 @@ -// Copyright 2020-present Etherna Sagl -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -namespace Etherna.ExecContext.AsyncLocal -{ - /// - /// Interface used by for comunicate with its - /// creator . - /// - internal interface IHandledAsyncLocalContext - { - void OnDisposed(IAsyncLocalContextHandler context); - } -} diff --git a/src/ExecutionContext/Exceptions/ExecutionContextNotFoundException.cs b/src/ExecutionContext/Exceptions/ExecutionContextNotFoundException.cs deleted file mode 100644 index 41998bfd..00000000 --- a/src/ExecutionContext/Exceptions/ExecutionContextNotFoundException.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2020-present Etherna Sagl -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System; - -namespace Etherna.ExecContext.Exceptions -{ - public class ExecutionContextNotFoundException : Exception - { - public ExecutionContextNotFoundException(string message) : base(message) - { } - - public ExecutionContextNotFoundException(string message, Exception innerException) : base(message, innerException) - { } - - public ExecutionContextNotFoundException() - { } - } -} diff --git a/src/ExecutionContext/ExecutionContext.csproj b/src/ExecutionContext/ExecutionContext.csproj deleted file mode 100644 index 2a6513fc..00000000 --- a/src/ExecutionContext/ExecutionContext.csproj +++ /dev/null @@ -1,42 +0,0 @@ - - - - netstandard2.0 - true - Etherna.ExecContext - Etherna Sagl - Execution context provider - 9.0 - enable - true - AllEnabledByDefault - - https://github.com/Etherna/mongodm - git - true - true - snupkg - LICENSE - true - true - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - True - - - - - diff --git a/src/ExecutionContext/ExecutionContextSelector.cs b/src/ExecutionContext/ExecutionContextSelector.cs deleted file mode 100644 index a055b954..00000000 --- a/src/ExecutionContext/ExecutionContextSelector.cs +++ /dev/null @@ -1,54 +0,0 @@ -// Copyright 2020-present Etherna Sagl -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System; -using System.Collections.Generic; - -namespace Etherna.ExecContext -{ - /// - /// A multi context selector that take different contexts, and select the first available. - /// - /// - /// This class is intended to have the same lifetime of it's consumer. For example, in case - /// of using with a DbContext, the same DbContext instance will use the same ContextSelector - /// instance. This mean that if a DbContext is running over different execution contexts, - /// every invoke on same context needs to return the same dictionary. - /// The simplest way to perform this, is to return the first not null available dictionary - /// on subscribed contexts. - /// - public class ExecutionContextSelector : IExecutionContext - { - // Fields. - private readonly IEnumerable contexts; - - // Constructors. - public ExecutionContextSelector(IEnumerable contexts) - { - this.contexts = contexts ?? throw new ArgumentNullException(nameof(contexts)); - } - - // Proeprties. - public IDictionary? Items - { - get - { - foreach (var context in contexts) - if (context.Items != null) - return context.Items; - return null; - } - } - } -} diff --git a/src/ExecutionContext/GlobalSuppressions.cs b/src/ExecutionContext/GlobalSuppressions.cs deleted file mode 100644 index 0e5488c9..00000000 --- a/src/ExecutionContext/GlobalSuppressions.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright 2020-present Etherna Sagl -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -// This file is used by Code Analysis to maintain SuppressMessage -// attributes that are applied to this project. -// Project-level suppressions either have no target or are given -// a specific target and scoped to a namespace, type, member, etc. - -using System.Diagnostics.CodeAnalysis; - -[assembly: SuppressMessage("Globalization", "CA1303:Do not pass literals as localized parameters", Justification = "This library will be not localized", Scope = "NamespaceAndDescendants", Target = "~N:Etherna.ExecContext")] diff --git a/src/ExecutionContext/IExecutionContext.cs b/src/ExecutionContext/IExecutionContext.cs deleted file mode 100644 index 28857b0f..00000000 --- a/src/ExecutionContext/IExecutionContext.cs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2020-present Etherna Sagl -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System.Collections.Generic; - -namespace Etherna.ExecContext -{ - /// - /// Represents an execution context, where information can be put and retrieve alongside - /// the process with a key-value dictionary. - /// - public interface IExecutionContext - { - /// - /// The context dictionary. - /// - IDictionary? Items { get; } - } -} diff --git a/src/ExecutionContext/Properties/AssemblyInfo.cs b/src/ExecutionContext/Properties/AssemblyInfo.cs deleted file mode 100644 index 3a8ab07a..00000000 --- a/src/ExecutionContext/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright 2020-present Etherna Sagl -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System; -using System.Runtime.CompilerServices; - -[assembly: CLSCompliant(false)] -[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] -[assembly: InternalsVisibleTo("ExecutionContext.Tests")] diff --git a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj index 5805ba8f..c0e65727 100644 --- a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj +++ b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj @@ -30,6 +30,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs index 00b85aaf..25b311fd 100644 --- a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs +++ b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs @@ -12,8 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -using Etherna.ExecContext; -using Etherna.ExecContext.AsyncLocal; +using Etherna.ExecContext.AspNetCore; using Etherna.MongODM.Core; using Etherna.MongODM.Core.Conventions; using Etherna.MongODM.Core.Domain.Models; @@ -24,7 +23,6 @@ using Etherna.MongODM.Core.Serialization.Modifiers; using Etherna.MongODM.Core.Tasks; using Etherna.MongODM.Core.Utility; -using Microsoft.AspNetCore.Http; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using MongoDB.Bson; @@ -76,14 +74,8 @@ public static IMongODMConfiguration AddMongODM(); + services.AddExecutionContext(); - services.TryAddSingleton(serviceProvider => - new ExecutionContextSelector(new IExecutionContext[] //default - { - new HttpContextExecutionContext(serviceProvider.GetRequiredService()), - AsyncLocalContext.Instance - })); services.TryAddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(); diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index a6d89a5e..60e56fca 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -23,6 +23,7 @@ + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -36,10 +37,6 @@ - - - - True diff --git a/test/ExecutionContext.Tests/AsyncLocal/AsyncLocalContextHandlerTests.cs b/test/ExecutionContext.Tests/AsyncLocal/AsyncLocalContextHandlerTests.cs deleted file mode 100644 index 3e8bea37..00000000 --- a/test/ExecutionContext.Tests/AsyncLocal/AsyncLocalContextHandlerTests.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright 2020-present Etherna Sagl -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using Moq; -using Xunit; - -namespace Etherna.ExecContext.AsyncLocal -{ - public class AsyncLocalContextHandlerTests - { - private readonly Mock handledContext; - private readonly AsyncLocalContextHandler handler; - - public AsyncLocalContextHandlerTests() - { - handledContext = new Mock(); - handler = new AsyncLocalContextHandler(handledContext.Object); - } - - [Fact] - public void Initialization() - { - // Assert. - Assert.Equal(handledContext.Object, handler.HandledContext); - } - - [Fact] - public void HandlerDispose() - { - // Action. - handler.Dispose(); - - // Assert. - handledContext.Verify(c => c.OnDisposed(handler), Times.Once); - } - } -} diff --git a/test/ExecutionContext.Tests/AsyncLocal/AsyncLocalContextTests.cs b/test/ExecutionContext.Tests/AsyncLocal/AsyncLocalContextTests.cs deleted file mode 100644 index b97c9d9d..00000000 --- a/test/ExecutionContext.Tests/AsyncLocal/AsyncLocalContextTests.cs +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright 2020-present Etherna Sagl -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using System.Threading.Tasks; -using Xunit; - -namespace Etherna.ExecContext.AsyncLocal -{ - public class AsyncLocalContextTests - { - private readonly AsyncLocalContext asyncLocalContext; - - public AsyncLocalContextTests() - { - asyncLocalContext = new AsyncLocalContext(); - } - - [Fact] - public void ItemsNullAtCreation() - { - // Assert. - Assert.Null(asyncLocalContext.Items); - } - - [Fact] - public async Task AsyncLocalLifeCycle() - { - await Task.Run(async () => - { - // Action. - asyncLocalContext.InitAsyncLocalContext(); - - // Assert. - Assert.NotNull(asyncLocalContext.Items); - await Task.Run(() => - { - Assert.NotNull(asyncLocalContext.Items); - }); - }); - - // Assert. - Assert.Null(asyncLocalContext.Items); - } - - [Fact] - public void SyncLocalLifeCycle() - { - void localMethod() - { - // Action. - asyncLocalContext.InitAsyncLocalContext(); - - // Assert. - Assert.NotNull(asyncLocalContext.Items); - void subLocalMethod() - { - Assert.NotNull(asyncLocalContext.Items); - } - subLocalMethod(); - } - localMethod(); - - // Assert. - /* Outside of an async invoker, the container is not automatically disposed. */ - Assert.NotNull(asyncLocalContext.Items); - } - - [Fact] - public void ContextDispose() - { - // Action. - using (var handler = asyncLocalContext.InitAsyncLocalContext()) - { - // Assert. - Assert.NotNull(asyncLocalContext.Items); - } - - // Assert. - Assert.Null(asyncLocalContext.Items); - } - } -} diff --git a/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj b/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj deleted file mode 100644 index 5628302f..00000000 --- a/test/ExecutionContext.Tests/ExecutionContext.Tests.csproj +++ /dev/null @@ -1,25 +0,0 @@ - - - - net5.0 - true - Etherna.ExecContext - false - enable - - - - - - - - all - runtime; build; native; contentfiles; analyzers; buildtransitive - - - - - - - - diff --git a/test/ExecutionContext.Tests/ExecutionContextSelectorTests.cs b/test/ExecutionContext.Tests/ExecutionContextSelectorTests.cs deleted file mode 100644 index 5310ed92..00000000 --- a/test/ExecutionContext.Tests/ExecutionContextSelectorTests.cs +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright 2020-present Etherna Sagl -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using Moq; -using System; -using System.Collections.Generic; -using Xunit; - -namespace Etherna.ExecContext -{ - public class ExecutionContextSelectorTests - { - [Theory] - [InlineData(false, false, null)] - [InlineData(false, true, "1")] - [InlineData(true, false, "0")] - [InlineData(true, true, "0")] - public void ContextSelection( - bool enableContext1, - bool enableContext2, - string expectedResult) - { - // Setup. - Mock context0 = new(); - Mock context1 = new(); - context0.SetupGet(c => c.Items) - .Returns(enableContext1 ? new Dictionary { { "val", "0" } } : null); - context1.SetupGet(c => c.Items) - .Returns(enableContext2 ? new Dictionary { { "val", "1" } } : null); - var selector = new ExecutionContextSelector(new[] { context0.Object, context1.Object }); - - // Action. - var result = selector.Items?["val"] as string; - - // Assert. - Assert.Equal(expectedResult, result); - } - } -} From a3a26a66946d48b78e28326a7d65a0b094a18d8c Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sun, 19 Sep 2021 19:30:49 +0200 Subject: [PATCH 17/78] Updated dependencies --- samples/AspNetCoreSample/Startup.cs | 3 ++- src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj | 2 +- src/MongODM.AspNetCore/MongODM.AspNetCore.csproj | 2 +- src/MongODM.Core/MongODM.Core.csproj | 6 +++--- src/MongODM.Hangfire/MongODM.Hangfire.csproj | 4 ++-- src/MongODM/MongODM.csproj | 4 ++-- test/MongODM.Core.Tests/MongODM.Core.Tests.csproj | 2 +- 7 files changed, 12 insertions(+), 11 deletions(-) diff --git a/samples/AspNetCoreSample/Startup.cs b/samples/AspNetCoreSample/Startup.cs index d81776ef..df8fcbf2 100644 --- a/samples/AspNetCoreSample/Startup.cs +++ b/samples/AspNetCoreSample/Startup.cs @@ -36,6 +36,8 @@ public void ConfigureServices(IServiceCollection services) { services.AddRazorPages(); + services.AddHangfireServer(); + services.AddMongODMWithHangfire() .AddDbContext(); @@ -53,7 +55,6 @@ public void Configure(IApplicationBuilder app) app.UseAuthorization(); - app.UseHangfireServer(); app.UseHangfireDashboard(); app.UseEndpoints(endpoints => diff --git a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj index 21953251..581c40b7 100644 --- a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj +++ b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj @@ -32,7 +32,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj index c0e65727..f9a7533c 100644 --- a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj +++ b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj @@ -31,7 +31,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index 60e56fca..8ef3d644 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -24,7 +24,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -32,8 +32,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/src/MongODM.Hangfire/MongODM.Hangfire.csproj b/src/MongODM.Hangfire/MongODM.Hangfire.csproj index cc5a8b9f..460d3dab 100644 --- a/src/MongODM.Hangfire/MongODM.Hangfire.csproj +++ b/src/MongODM.Hangfire/MongODM.Hangfire.csproj @@ -22,11 +22,11 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index 075dc3ad..7382a403 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -26,11 +26,11 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj index 10245eac..effe5991 100644 --- a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj +++ b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj @@ -9,7 +9,7 @@ - + From 251cd57e631e889202cf1da8e74d3500b830d0c7 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sun, 19 Sep 2021 22:32:27 +0200 Subject: [PATCH 18/78] Fixed MODM-90 --- .../Serialization/Mapping/ModelMap.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/MongODM.Core/Serialization/Mapping/ModelMap.cs b/src/MongODM.Core/Serialization/Mapping/ModelMap.cs index 4dab9ff8..a96ff0e3 100644 --- a/src/MongODM.Core/Serialization/Mapping/ModelMap.cs +++ b/src/MongODM.Core/Serialization/Mapping/ModelMap.cs @@ -17,6 +17,8 @@ using Etherna.MongODM.Core.Utility; using MongoDB.Bson.Serialization; using System; +using System.Linq; +using System.Reflection; namespace Etherna.MongODM.Core.Serialization.Mapping { @@ -81,6 +83,22 @@ public void UseProxyGenerator(IDbContext dbContext) => if (ModelType.IsAbstract) throw new InvalidOperationException("Can't generate proxy of an abstract model"); + // Remove CreatorMaps. + while (BsonClassMap.CreatorMaps.Any()) + { + var memberInfo = BsonClassMap.CreatorMaps.First().MemberInfo; + switch (memberInfo) + { + case ConstructorInfo constructorInfo: + BsonClassMap.UnmapConstructor(constructorInfo); + break; + case MethodInfo methodInfo: + BsonClassMap.UnmapFactoryMethod(methodInfo); + break; + default: throw new InvalidOperationException(); + } + } + // Set creator. BsonClassMap.SetCreator(() => dbContext.ProxyGenerator.CreateInstance(ModelType, dbContext)); }); From 64a2d9634da14e98ce492b568956f68a54b70e7e Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Mon, 20 Sep 2021 20:02:36 +0200 Subject: [PATCH 19/78] Implemented MODM-91 --- .../Repositories/CollectionRepository.cs | 22 +++++++++++++++++ .../Repositories/ICollectionRepository.cs | 7 ++++++ .../Repositories/PaginatedEnumerable.cs | 24 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 src/MongODM.Core/Repositories/PaginatedEnumerable.cs diff --git a/src/MongODM.Core/Repositories/CollectionRepository.cs b/src/MongODM.Core/Repositories/CollectionRepository.cs index 8588fa06..13c24b47 100644 --- a/src/MongODM.Core/Repositories/CollectionRepository.cs +++ b/src/MongODM.Core/Repositories/CollectionRepository.cs @@ -14,6 +14,7 @@ using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Exceptions; +using Etherna.MongODM.Core.Extensions; using Etherna.MongODM.Core.ProxyModels; using Etherna.MongODM.Core.Serialization.Mapping; using MongoDB.Bson; @@ -129,6 +130,27 @@ public virtual Task QueryElementsAsync( return query(Collection.AsQueryable(aggregateOptions)); } + public async Task> QueryPaginatedElementsAsync( + Func, IMongoQueryable> filter, + Expression> orderKeySelector, + int page, + int take, + CancellationToken cancellationToken = default) + { + var elements = await QueryElementsAsync(elements => filter(elements) + .Paginate(orderKeySelector, page, take) + .ToListAsync(cancellationToken)).ConfigureAwait(false); + + var maxPage = (await QueryElementsAsync(elements => filter(elements) + .CountAsync(cancellationToken)).ConfigureAwait(false) - 1) / take; + + return new PaginatedEnumerable( + elements, + page, + take, + maxPage); + } + public virtual Task ReplaceAsync( object model, bool updateDependentDocuments = true, diff --git a/src/MongODM.Core/Repositories/ICollectionRepository.cs b/src/MongODM.Core/Repositories/ICollectionRepository.cs index 6514cbbc..6ec73972 100644 --- a/src/MongODM.Core/Repositories/ICollectionRepository.cs +++ b/src/MongODM.Core/Repositories/ICollectionRepository.cs @@ -54,6 +54,13 @@ Task QueryElementsAsync( Func, Task> query, AggregateOptions? aggregateOptions = null); + Task> QueryPaginatedElementsAsync( + Func, IMongoQueryable> filter, + Expression> orderKeySelector, + int page, + int take, + CancellationToken cancellationToken = default); + Task ReplaceAsync( TModel model, bool updateDependentDocuments = true, diff --git a/src/MongODM.Core/Repositories/PaginatedEnumerable.cs b/src/MongODM.Core/Repositories/PaginatedEnumerable.cs new file mode 100644 index 00000000..6f2c9a09 --- /dev/null +++ b/src/MongODM.Core/Repositories/PaginatedEnumerable.cs @@ -0,0 +1,24 @@ +using System.Collections.Generic; + +namespace Etherna.MongODM.Core.Repositories +{ + public class PaginatedEnumerable + { + public PaginatedEnumerable( + IEnumerable elements, + int currentPage, + int pageSize, + int maxPage) + { + CurrentPage = currentPage; + Elements = elements; + MaxPage = maxPage; + PageSize = pageSize; + } + + public int CurrentPage { get; } + public IEnumerable Elements { get; } + public int MaxPage { get; } + public int PageSize { get; } + } +} From 0258b16717567cad9b622cde1071ade301f294b8 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Thu, 4 Nov 2021 22:07:24 +0100 Subject: [PATCH 20/78] Updated dependencies --- src/MongODM.Core/MongODM.Core.csproj | 4 ++-- src/MongODM.Hangfire/MongODM.Hangfire.csproj | 2 +- src/MongODM/MongODM.csproj | 2 +- test/MongODM.Core.Tests/MongODM.Core.Tests.csproj | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index 8ef3d644..93554dcb 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -32,8 +32,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/src/MongODM.Hangfire/MongODM.Hangfire.csproj b/src/MongODM.Hangfire/MongODM.Hangfire.csproj index 460d3dab..3ab55583 100644 --- a/src/MongODM.Hangfire/MongODM.Hangfire.csproj +++ b/src/MongODM.Hangfire/MongODM.Hangfire.csproj @@ -26,7 +26,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index 7382a403..83a63869 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -30,7 +30,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj index effe5991..8e27e176 100644 --- a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj +++ b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj @@ -9,7 +9,7 @@ - + From fb529b99b05fe104ed269628ae5a31907d6b81d3 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Thu, 4 Nov 2021 22:14:23 +0100 Subject: [PATCH 21/78] Removed support to netcoreapp2.1 --- .github/workflows/myget-unstable-deploy.yml | 5 ----- .github/workflows/nuget-stable-deploy.yml | 5 ----- src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj | 2 +- src/MongODM.AspNetCore/MongODM.AspNetCore.csproj | 2 +- src/MongODM/MongODM.csproj | 2 +- 5 files changed, 3 insertions(+), 13 deletions(-) diff --git a/.github/workflows/myget-unstable-deploy.yml b/.github/workflows/myget-unstable-deploy.yml index 7e3aef43..69780800 100644 --- a/.github/workflows/myget-unstable-deploy.yml +++ b/.github/workflows/myget-unstable-deploy.yml @@ -15,11 +15,6 @@ jobs: with: fetch-depth: 0 - - name: Setup .NET Core SDK 2.1.x - uses: actions/setup-dotnet@v1 - with: - dotnet-version: '2.1.x' - - name: Setup .NET Core SDK 3.1.x uses: actions/setup-dotnet@v1 with: diff --git a/.github/workflows/nuget-stable-deploy.yml b/.github/workflows/nuget-stable-deploy.yml index cb97bcd4..6d298437 100644 --- a/.github/workflows/nuget-stable-deploy.yml +++ b/.github/workflows/nuget-stable-deploy.yml @@ -13,11 +13,6 @@ jobs: - uses: actions/checkout@master with: fetch-depth: 0 - - - name: Setup .NET Core SDK 2.1.x - uses: actions/setup-dotnet@v1 - with: - dotnet-version: '2.1.x' - name: Setup .NET Core SDK 3.1.x uses: actions/setup-dotnet@v1 diff --git a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj index 581c40b7..82923210 100644 --- a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj +++ b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1;netcoreapp3.1 + netcoreapp3.1 true true diff --git a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj index f9a7533c..9c4adb8b 100644 --- a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj +++ b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1;netcoreapp3.1;net5.0 + netcoreapp3.1;net5.0 true Etherna.MongODM.AspNetCore Etherna Sagl diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index 83a63869..f8322eaa 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -1,7 +1,7 @@  - netcoreapp2.1;netcoreapp3.1;net5.0 + netcoreapp3.1;net5.0 true Etherna.MongODM Etherna Sagl From d5c61e0731931b105c6e2fc37cb89288e8bc1033 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sun, 7 Nov 2021 18:21:02 +0100 Subject: [PATCH 22/78] Fixed MODM-92 and other related bugs --- .../MongODMConfiguration.cs | 3 ++- .../ServiceCollectionExtensions.cs | 2 +- .../MongodmIndexBuildingException.cs | 19 +++++++++++++++++++ .../Repositories/CollectionRepository.cs | 11 +++++++++-- 4 files changed, 31 insertions(+), 4 deletions(-) create mode 100644 src/MongODM.Core/Exceptions/MongodmIndexBuildingException.cs diff --git a/src/MongODM.AspNetCore/MongODMConfiguration.cs b/src/MongODM.AspNetCore/MongODMConfiguration.cs index 8fcc22d5..2b8cd56e 100644 --- a/src/MongODM.AspNetCore/MongODMConfiguration.cs +++ b/src/MongODM.AspNetCore/MongODMConfiguration.cs @@ -103,7 +103,7 @@ public IMongODMConfiguration AddDbContext( throw new InvalidOperationException("Configuration is frozen"); // Register dbContext. - services.AddSingleton(sp => + services.AddSingleton(sp => { // Get dependencies. var dependencies = sp.GetRequiredService(); @@ -119,6 +119,7 @@ public IMongODMConfiguration AddDbContext( return dbContext; }); + services.AddSingleton(sp => sp.GetRequiredService()); // Add db context type. dbContextTypes.Add(typeof(TDbContext)); diff --git a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs index 25b311fd..08876167 100644 --- a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs +++ b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs @@ -78,7 +78,7 @@ public static IMongODMConfiguration AddMongODM(); services.TryAddSingleton(); - services.TryAddSingleton(); + services.TryAddSingleton(sp => (TTaskRunner)sp.GetRequiredService()); // DbContext internal. //dependencies diff --git a/src/MongODM.Core/Exceptions/MongodmIndexBuildingException.cs b/src/MongODM.Core/Exceptions/MongodmIndexBuildingException.cs new file mode 100644 index 00000000..f57f5c47 --- /dev/null +++ b/src/MongODM.Core/Exceptions/MongodmIndexBuildingException.cs @@ -0,0 +1,19 @@ +using System; + +namespace Etherna.MongODM.Core.Exceptions +{ + public class MongodmIndexBuildingException : Exception + { + public MongodmIndexBuildingException() + { + } + + public MongodmIndexBuildingException(string message) : base(message) + { + } + + public MongodmIndexBuildingException(string message, Exception innerException) : base(message, innerException) + { + } + } +} diff --git a/src/MongODM.Core/Repositories/CollectionRepository.cs b/src/MongODM.Core/Repositories/CollectionRepository.cs index 13c24b47..4fcaf52d 100644 --- a/src/MongODM.Core/Repositories/CollectionRepository.cs +++ b/src/MongODM.Core/Repositories/CollectionRepository.cs @@ -64,8 +64,15 @@ public override async Task BuildIndexesAsync(ISchemaRegister schemaRegister, Can var (keys, options) = pair; if (options.Name == null) { - var renderedKeys = keys.Render(Collection.DocumentSerializer, Collection.Settings.SerializerRegistry); - options.Name = $"doc_{ string.Join("_", renderedKeys.Names) }"; + try + { + var renderedKeys = keys.Render(Collection.DocumentSerializer, Collection.Settings.SerializerRegistry); + options.Name = $"doc_{ string.Join("_", renderedKeys.Names) }"; + } + catch (InvalidOperationException) + { + throw new MongodmIndexBuildingException($"Can't build custom index in collection \"{Name}\""); + } } return (options.Name, new CreateIndexModel(keys, options)); From 10cec2a1884add149994ab1a9f3f564c3345bc99 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Mon, 29 Nov 2021 02:12:17 +0100 Subject: [PATCH 23/78] Fixed warnings --- src/MongODM.Core/Repositories/CollectionRepository.cs | 2 +- src/MongODM.Core/Repositories/GridFSRepository.cs | 2 +- src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs | 2 -- .../Serialization/Serializers/ReferenceSerializer.cs | 2 -- 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/src/MongODM.Core/Repositories/CollectionRepository.cs b/src/MongODM.Core/Repositories/CollectionRepository.cs index 4fcaf52d..8f767024 100644 --- a/src/MongODM.Core/Repositories/CollectionRepository.cs +++ b/src/MongODM.Core/Repositories/CollectionRepository.cs @@ -98,7 +98,7 @@ public override async Task BuildIndexesAsync(ISchemaRegister schemaRegister, Can // Get current indexes. var currentIndexes = new List(); using (var indexList = await Collection.Indexes.ListAsync(cancellationToken).ConfigureAwait(false)) - while (indexList.MoveNext(cancellationToken)) + while (await indexList.MoveNextAsync(cancellationToken).ConfigureAwait(false)) currentIndexes.AddRange(indexList.Current); // Remove old indexes. diff --git a/src/MongODM.Core/Repositories/GridFSRepository.cs b/src/MongODM.Core/Repositories/GridFSRepository.cs index e60b8f36..1f1bed4c 100644 --- a/src/MongODM.Core/Repositories/GridFSRepository.cs +++ b/src/MongODM.Core/Repositories/GridFSRepository.cs @@ -97,7 +97,7 @@ protected override async Task FindOneOnDBAsync(string id, CancellationTo throw new ArgumentNullException(nameof(id)); var filter = Builders.Filter.Eq("_id", ObjectId.Parse(id)); - var mongoFile = await GridFSBucket.Find(filter, cancellationToken: cancellationToken) + var mongoFile = await(await GridFSBucket.FindAsync(filter, cancellationToken: cancellationToken).ConfigureAwait(false)) .SingleOrDefaultAsync(cancellationToken).ConfigureAwait(false); if (mongoFile == null) throw new MongodmEntityNotFoundException($"Can't find key {id}"); diff --git a/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs b/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs index b1aeb657..3c12545b 100644 --- a/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs @@ -306,9 +306,7 @@ private void CompileDependencyRegisters( //model maps schema serializers if (memberSerializer is IModelMapsContainerSerializer schemaSerializer) { -#pragma warning disable CA1508 // Avoid dead conditional code. Here code analyzer is wrong bool? useCascadeDelete = (memberSerializer as IReferenceContainerSerializer)?.UseCascadeDelete; -#pragma warning restore CA1508 // Avoid dead conditional code foreach (var childClassMap in schemaSerializer.AllChildClassMaps) CompileDependencyRegisters(modelMap, childClassMap, lastEntityClassMap, currentMemberPath, useCascadeDelete); } diff --git a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs index f1d60732..b6e545e1 100644 --- a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs @@ -153,10 +153,8 @@ public override TModelBase Deserialize(BsonDeserializationContext context, BsonD if (model != null) { var id = model.Id; -#pragma warning disable CA1508 // Avoid dead conditional code if (id == null) //ignore refered instances without id return null!; -#pragma warning restore CA1508 // Avoid dead conditional code // Check if model as been loaded in cache. if (dbContext.DbCache.LoadedModels.ContainsKey(id) && From 57ad97cc327043c1ebe496eee7d3fc00f1bc83d2 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Mon, 29 Nov 2021 02:18:37 +0100 Subject: [PATCH 24/78] Allow generic serializers without "class" restriction --- src/MongODM.Core/Extensions/BsonClassMapExtensions.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/MongODM.Core/Extensions/BsonClassMapExtensions.cs b/src/MongODM.Core/Extensions/BsonClassMapExtensions.cs index 22a732dd..6834a3a1 100644 --- a/src/MongODM.Core/Extensions/BsonClassMapExtensions.cs +++ b/src/MongODM.Core/Extensions/BsonClassMapExtensions.cs @@ -41,7 +41,6 @@ public static BsonMemberMap SetMemberSerializer( this BsonClassMap classMap, Expression> memberLambda, IBsonSerializer serializer) - where TMember : class { if (classMap is null) throw new ArgumentNullException(nameof(classMap)); From f421c57d7c32d538e2ea68bd2915fbf4cbef5583 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Mon, 29 Nov 2021 02:25:16 +0100 Subject: [PATCH 25/78] Reverted some fixes (doesn't compile on github) --- src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs | 2 ++ .../Serialization/Serializers/ReferenceSerializer.cs | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs b/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs index 3c12545b..b1aeb657 100644 --- a/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs @@ -306,7 +306,9 @@ private void CompileDependencyRegisters( //model maps schema serializers if (memberSerializer is IModelMapsContainerSerializer schemaSerializer) { +#pragma warning disable CA1508 // Avoid dead conditional code. Here code analyzer is wrong bool? useCascadeDelete = (memberSerializer as IReferenceContainerSerializer)?.UseCascadeDelete; +#pragma warning restore CA1508 // Avoid dead conditional code foreach (var childClassMap in schemaSerializer.AllChildClassMaps) CompileDependencyRegisters(modelMap, childClassMap, lastEntityClassMap, currentMemberPath, useCascadeDelete); } diff --git a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs index b6e545e1..f1d60732 100644 --- a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs @@ -153,8 +153,10 @@ public override TModelBase Deserialize(BsonDeserializationContext context, BsonD if (model != null) { var id = model.Id; +#pragma warning disable CA1508 // Avoid dead conditional code if (id == null) //ignore refered instances without id return null!; +#pragma warning restore CA1508 // Avoid dead conditional code // Check if model as been loaded in cache. if (dbContext.DbCache.LoadedModels.ContainsKey(id) && From 19ec97490597fff07981b07e51e7795c1b7c5838 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Wed, 1 Dec 2021 01:24:20 +0100 Subject: [PATCH 26/78] Updated dependencies --- src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj | 2 +- src/MongODM.AspNetCore/MongODM.AspNetCore.csproj | 2 +- src/MongODM.Core/MongODM.Core.csproj | 6 +++--- src/MongODM.Hangfire/MongODM.Hangfire.csproj | 2 +- src/MongODM/MongODM.csproj | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj index 82923210..acd5996b 100644 --- a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj +++ b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj @@ -32,7 +32,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj index 9c4adb8b..338293cb 100644 --- a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj +++ b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj @@ -31,7 +31,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index 93554dcb..bb3d64e7 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -24,7 +24,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive @@ -32,8 +32,8 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + diff --git a/src/MongODM.Hangfire/MongODM.Hangfire.csproj b/src/MongODM.Hangfire/MongODM.Hangfire.csproj index 3ab55583..514b681f 100644 --- a/src/MongODM.Hangfire/MongODM.Hangfire.csproj +++ b/src/MongODM.Hangfire/MongODM.Hangfire.csproj @@ -22,7 +22,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index f8322eaa..a27b3ed6 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -26,7 +26,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 517ce8021979b23f7ed93f80be1c01920b94cd4d Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Wed, 1 Dec 2021 17:42:30 +0100 Subject: [PATCH 27/78] Added DiscriminatorRegister with discriminator registration --- src/MongODM.AspNetCore/DbDependencies.cs | 3 ++ .../ServiceCollectionExtensions.cs | 1 + src/MongODM.Core/DbContext.cs | 2 + src/MongODM.Core/IDbContext.cs | 5 ++ src/MongODM.Core/IDbDependencies.cs | 1 + .../Mapping/DiscriminatorRegister.cs | 54 +++++++++++++++++++ .../Mapping/IDiscriminatorRegister.cs | 10 ++++ .../Serialization/Mapping/SchemaRegister.cs | 2 +- 8 files changed, 77 insertions(+), 1 deletion(-) create mode 100644 src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs create mode 100644 src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs diff --git a/src/MongODM.AspNetCore/DbDependencies.cs b/src/MongODM.AspNetCore/DbDependencies.cs index 349e1aca..8cce70c7 100644 --- a/src/MongODM.AspNetCore/DbDependencies.cs +++ b/src/MongODM.AspNetCore/DbDependencies.cs @@ -30,6 +30,7 @@ public DbDependencies( IDbCache dbCache, IDbMaintainer dbMaintainer, IDbMigrationManager dbContextMigrationManager, + IDiscriminatorRegister discriminatorRegister, IOptions mongODMOptions, IProxyGenerator proxyGenerator, IRepositoryRegister repositoryRegister, @@ -42,6 +43,7 @@ public DbDependencies( DbCache = dbCache; DbMaintainer = dbMaintainer; DbMigrationManager = dbContextMigrationManager; + DiscriminatorRegister = discriminatorRegister; MongODMOptions = mongODMOptions.Value; SchemaRegister = schemaRegister; ProxyGenerator = proxyGenerator; @@ -52,6 +54,7 @@ public DbDependencies( public IDbCache DbCache { get; } public IDbMaintainer DbMaintainer { get; } public IDbMigrationManager DbMigrationManager { get; } + public IDiscriminatorRegister DiscriminatorRegister { get; } public MongODMOptions MongODMOptions { get; } public IProxyGenerator ProxyGenerator { get; } public IRepositoryRegister RepositoryRegister { get; } diff --git a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs index 08876167..a73963bd 100644 --- a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs +++ b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs @@ -91,6 +91,7 @@ public static IMongODMConfiguration AddMongODM(); services.TryAddTransient(); services.TryAddTransient(); + services.TryAddTransient(); services.TryAddTransient(); services.TryAddTransient(); services.TryAddSingleton(); diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index d0d35409..ccabcd4a 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -56,6 +56,7 @@ public async Task InitializeAsync( DbMaintainer = dependencies.DbMaintainer; DbMigrationManager = dependencies.DbMigrationManager; DbOperations = new CollectionRepository(options.DbOperationsCollectionName); + DiscriminatorRegister = dependencies.DiscriminatorRegister; LibraryVersion = typeof(DbContext) .GetTypeInfo() .Assembly @@ -115,6 +116,7 @@ public async Task InitializeAsync( public IDbMaintainer DbMaintainer { get; private set; } = default!; public IDbMigrationManager DbMigrationManager { get; private set; } = default!; public ICollectionRepository DbOperations { get; private set; } = default!; + public IDiscriminatorRegister DiscriminatorRegister { get; private set; } = default!; public virtual IEnumerable DocumentMigrationList { get; } = Array.Empty(); public string Identifier => Options?.Identifier ?? GetType().Name; public SemanticVersion LibraryVersion { get; private set; } = default!; diff --git a/src/MongODM.Core/IDbContext.cs b/src/MongODM.Core/IDbContext.cs index 0c179b1b..faa359e3 100644 --- a/src/MongODM.Core/IDbContext.cs +++ b/src/MongODM.Core/IDbContext.cs @@ -64,6 +64,11 @@ public interface IDbContext /// ICollectionRepository DbOperations { get; } + /// + /// Register for discriminator configuration. + /// + IDiscriminatorRegister DiscriminatorRegister { get; } + /// /// List of registered migration tasks /// diff --git a/src/MongODM.Core/IDbDependencies.cs b/src/MongODM.Core/IDbDependencies.cs index 4caf1e7a..d6afc4cf 100644 --- a/src/MongODM.Core/IDbDependencies.cs +++ b/src/MongODM.Core/IDbDependencies.cs @@ -25,6 +25,7 @@ public interface IDbDependencies IDbCache DbCache { get; } IDbMaintainer DbMaintainer { get; } IDbMigrationManager DbMigrationManager { get; } + IDiscriminatorRegister DiscriminatorRegister { get; } IProxyGenerator ProxyGenerator { get; } IRepositoryRegister RepositoryRegister { get; } ISchemaRegister SchemaRegister { get; } diff --git a/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs new file mode 100644 index 00000000..232fa3bf --- /dev/null +++ b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs @@ -0,0 +1,54 @@ +using MongoDB.Bson; +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Threading; + +namespace Etherna.MongODM.Core.Serialization.Mapping +{ + public class DiscriminatorRegister : IDiscriminatorRegister + { + // Fields. + private readonly ReaderWriterLockSlim configLock = new(LockRecursionPolicy.SupportsRecursion); + private readonly Dictionary> discriminators = new(); + private readonly HashSet discriminatedTypes = new(); + + // Methods. + public void AddDiscriminator(Type type, BsonValue discriminator) + { + // Checks. + if (type is null) + throw new ArgumentNullException(nameof(type)); + if (discriminator is null) + throw new ArgumentNullException(nameof(discriminator)); + + var typeInfo = type.GetTypeInfo(); + if (typeInfo.IsInterface) + throw new BsonSerializationException($"Discriminators can only be registered for classes, not for interface {type.FullName}."); + + // Add discriminator. + configLock.EnterWriteLock(); + try + { + if (!discriminators.TryGetValue(discriminator, out HashSet hashSet)) + { + hashSet = new HashSet(); + discriminators.Add(discriminator, hashSet); + } + + if (!hashSet.Contains(type)) + { + hashSet.Add(type); + + //mark all base types as discriminated (so we know that it's worth reading a discriminator) + for (var baseType = typeInfo.BaseType; baseType != null; baseType = baseType.GetTypeInfo().BaseType) + discriminatedTypes.Add(baseType); + } + } + finally + { + configLock.ExitWriteLock(); + } + } + } +} diff --git a/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs b/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs new file mode 100644 index 00000000..7ba0c87d --- /dev/null +++ b/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs @@ -0,0 +1,10 @@ +using MongoDB.Bson; +using System; + +namespace Etherna.MongODM.Core.Serialization.Mapping +{ + public interface IDiscriminatorRegister + { + void AddDiscriminator(Type type, BsonValue discriminator); + } +} \ No newline at end of file diff --git a/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs b/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs index b1aeb657..e275cd61 100644 --- a/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs @@ -204,7 +204,7 @@ protected override void FreezeAction() // Register discriminators for all bson class maps. if (schema is IModelMapsSchema modelMapsSchema) foreach (var modelMap in modelMapsSchema.AllMapsDictionary.Values) - BsonSerializer.RegisterDiscriminator(modelMapsSchema.ModelType, modelMap.BsonClassMap.Discriminator); + dbContext.DiscriminatorRegister.AddDiscriminator(modelMapsSchema.ModelType, modelMap.BsonClassMap.Discriminator); } // Specific for model maps schemas. From 080c386c8f261eac66640e89bac23b5d4d432f3c Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Wed, 1 Dec 2021 18:03:23 +0100 Subject: [PATCH 28/78] Added registration of discriminator conventions --- samples/AspNetCoreSample/Startup.cs | 2 +- .../ServiceCollectionExtensions.cs | 18 ++++----------- src/MongODM.Core/DbContext.cs | 5 ++++ .../Mapping/DiscriminatorRegister.cs | 23 +++++++++++++++++++ .../Mapping/IDiscriminatorRegister.cs | 2 ++ src/MongODM/ServiceCollectionExtensions.cs | 11 ++++----- 6 files changed, 39 insertions(+), 22 deletions(-) diff --git a/samples/AspNetCoreSample/Startup.cs b/samples/AspNetCoreSample/Startup.cs index df8fcbf2..4d119c5a 100644 --- a/samples/AspNetCoreSample/Startup.cs +++ b/samples/AspNetCoreSample/Startup.cs @@ -38,7 +38,7 @@ public void ConfigureServices(IServiceCollection services) services.AddHangfireServer(); - services.AddMongODMWithHangfire() + services.AddMongODMWithHangfire() .AddDbContext(); services.AddMongODMAdminDashboard(); diff --git a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs index a73963bd..8f3a8140 100644 --- a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs +++ b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs @@ -14,8 +14,6 @@ using Etherna.ExecContext.AspNetCore; using Etherna.MongODM.Core; -using Etherna.MongODM.Core.Conventions; -using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Options; using Etherna.MongODM.Core.ProxyModels; using Etherna.MongODM.Core.Repositories; @@ -26,7 +24,6 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using MongoDB.Bson; -using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Conventions; using System; @@ -34,19 +31,17 @@ namespace Etherna.MongODM.AspNetCore { public static class ServiceCollectionExtensions { - public static IMongODMConfiguration AddMongODM( + public static IMongODMConfiguration AddMongODM( this IServiceCollection services, Action? configureOptions = null) - where TTaskRunner : class, ITaskRunner, ITaskRunnerBuilder - where TModelBase : class, IModel => //needed because of this https://jira.mongodb.org/browse/CSHARP-3154 - AddMongODM(services, configureOptions); + where TTaskRunner : class, ITaskRunner, ITaskRunnerBuilder => + AddMongODM(services, configureOptions); - public static IMongODMConfiguration AddMongODM( + public static IMongODMConfiguration AddMongODM( this IServiceCollection services, Action? configureOptions = null) where TProxyGenerator : class, IProxyGenerator where TTaskRunner : class, ITaskRunner, ITaskRunnerBuilder - where TModelBase : class, IModel //needed because of this https://jira.mongodb.org/browse/CSHARP-3154 { // MongODM generic configuration. var configuration = new MongODMConfiguration(services); @@ -62,11 +57,6 @@ public static IMongODMConfiguration AddMongODM true); - BsonSerializer.RegisterDiscriminatorConvention(typeof(TModelBase), - new HierarchicalProxyTolerantDiscriminatorConvention("_t", proxyGenerator)); - BsonSerializer.RegisterDiscriminatorConvention(typeof(EntityModelBase), - new HierarchicalProxyTolerantDiscriminatorConvention("_t", proxyGenerator)); - // Freeze configuration into mongodm options. configuration.Freeze(options); diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index ccabcd4a..10c7d35f 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongODM.Core.Conventions; using Etherna.MongODM.Core.Domain.ModelMaps; using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Migration; @@ -94,6 +95,10 @@ public async Task InitializeAsync( foreach (var maps in ModelMapsCollectors) maps.Register(this); + // Initialize conventions. + DiscriminatorRegister.AddDiscriminatorConvention(typeof(object), + new HierarchicalProxyTolerantDiscriminatorConvention("_t", ProxyGenerator)); + // Build and freeze schemas register. SchemaRegister.Freeze(); diff --git a/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs index 232fa3bf..dc248c06 100644 --- a/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs @@ -1,4 +1,5 @@ using MongoDB.Bson; +using MongoDB.Bson.Serialization.Conventions; using System; using System.Collections.Generic; using System.Reflection; @@ -10,6 +11,7 @@ public class DiscriminatorRegister : IDiscriminatorRegister { // Fields. private readonly ReaderWriterLockSlim configLock = new(LockRecursionPolicy.SupportsRecursion); + private readonly Dictionary discriminatorConventions = new(); private readonly Dictionary> discriminators = new(); private readonly HashSet discriminatedTypes = new(); @@ -50,5 +52,26 @@ public void AddDiscriminator(Type type, BsonValue discriminator) configLock.ExitWriteLock(); } } + + public void AddDiscriminatorConvention(Type type, IDiscriminatorConvention convention) + { + if (type is null) + throw new ArgumentNullException(nameof(type)); + if (convention is null) + throw new ArgumentNullException(nameof(convention)); + + configLock.EnterWriteLock(); + try + { + if (!discriminatorConventions.ContainsKey(type)) + discriminatorConventions.Add(type, convention); + else + throw new BsonSerializationException($"There is already a discriminator convention registered for type {type.FullName}."); + } + finally + { + configLock.ExitWriteLock(); + } + } } } diff --git a/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs b/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs index 7ba0c87d..9f673756 100644 --- a/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs @@ -1,4 +1,5 @@ using MongoDB.Bson; +using MongoDB.Bson.Serialization.Conventions; using System; namespace Etherna.MongODM.Core.Serialization.Mapping @@ -6,5 +7,6 @@ namespace Etherna.MongODM.Core.Serialization.Mapping public interface IDiscriminatorRegister { void AddDiscriminator(Type type, BsonValue discriminator); + void AddDiscriminatorConvention(Type type, IDiscriminatorConvention convention); } } \ No newline at end of file diff --git a/src/MongODM/ServiceCollectionExtensions.cs b/src/MongODM/ServiceCollectionExtensions.cs index 413c3678..af304971 100644 --- a/src/MongODM/ServiceCollectionExtensions.cs +++ b/src/MongODM/ServiceCollectionExtensions.cs @@ -13,7 +13,6 @@ // limitations under the License. using Etherna.MongODM.AspNetCore; -using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Options; using Etherna.MongODM.Core.ProxyModels; using Etherna.MongODM.HF.Tasks; @@ -27,14 +26,13 @@ namespace Etherna.MongODM public static class ServiceCollectionExtensions { // Methods. - public static IMongODMConfiguration AddMongODMWithHangfire( + public static IMongODMConfiguration AddMongODMWithHangfire( this IServiceCollection services, Action? configureHangfireOptions = null, Action? configureMongODMOptions = null) - where TModelBase : class, IModel { // Configure MongODM. - var conf = services.AddMongODM(configureMongODMOptions); + var conf = services.AddMongODM(configureMongODMOptions); // Configure Hangfire. AddHangfire(services, configureHangfireOptions); @@ -42,15 +40,14 @@ public static IMongODMConfiguration AddMongODMWithHangfire( return conf; } - public static IMongODMConfiguration AddMongODMWithHangfire( + public static IMongODMConfiguration AddMongODMWithHangfire( this IServiceCollection services, Action? configureHangfireOptions = null, Action? configureMongODMOptions = null) where TProxyGenerator : class, IProxyGenerator - where TModelBase : class, IModel { // Configure MongODM. - var conf = services.AddMongODM(configureMongODMOptions); + var conf = services.AddMongODM(configureMongODMOptions); // Configure Hangfire. AddHangfire(services, configureHangfireOptions); From 7120614d8264e61dc02cf47d7db17de043a01279 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Wed, 1 Dec 2021 21:31:30 +0100 Subject: [PATCH 29/78] Implemented DiscriminatorRegister.LookupDiscriminatorConvention(Type) --- src/MongODM.Core/DbContext.cs | 4 -- .../Domain/ModelMaps/OperationBaseMap.cs | 7 +- src/MongODM.Core/Properties/IsExternalInit.cs | 5 ++ .../Mapping/DiscriminatorRegister.cs | 71 ++++++++++++++++++- .../Mapping/IDiscriminatorRegister.cs | 6 +- .../Serialization/Mapping/ModelMap.cs | 7 +- .../Serializers/ModelMapSerializer.cs | 47 ++++++------ .../Serializers/ReferenceSerializer.cs | 2 +- .../ModelMapSerializerTest.cs | 47 +++++------- 9 files changed, 120 insertions(+), 76 deletions(-) create mode 100644 src/MongODM.Core/Properties/IsExternalInit.cs diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index 10c7d35f..fe155bfe 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -95,10 +95,6 @@ public async Task InitializeAsync( foreach (var maps in ModelMapsCollectors) maps.Register(this); - // Initialize conventions. - DiscriminatorRegister.AddDiscriminatorConvention(typeof(object), - new HierarchicalProxyTolerantDiscriminatorConvention("_t", ProxyGenerator)); - // Build and freeze schemas register. SchemaRegister.Freeze(); diff --git a/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs b/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs index d2e8904e..a75ad3d3 100644 --- a/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs +++ b/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs @@ -25,15 +25,12 @@ public void Register(IDbContext dbContext) { dbContext.SchemaRegister.AddModelMapsSchema("ee726d4f-6e6a-44b0-bf3e-45322534c36d", customSerializer: new ModelMapSerializer( - dbContext.DbCache, + dbContext, new DocumentSemVerOptions { CurrentVersion = dbContext.LibraryVersion, WriteInDocuments = false - }, - dbContext.Options.ModelMapVersion, - dbContext.SchemaRegister, - dbContext.SerializerModifierAccessor)); + })); } } } diff --git a/src/MongODM.Core/Properties/IsExternalInit.cs b/src/MongODM.Core/Properties/IsExternalInit.cs new file mode 100644 index 00000000..d3603fa5 --- /dev/null +++ b/src/MongODM.Core/Properties/IsExternalInit.cs @@ -0,0 +1,5 @@ +// Required because of this https://developercommunity.visualstudio.com/t/error-cs0518-predefined-type-systemruntimecompiler/1244809 +namespace System.Runtime.CompilerServices +{ + internal static class IsExternalInit { } +} \ No newline at end of file diff --git a/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs index dc248c06..6c27ce44 100644 --- a/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs @@ -1,4 +1,6 @@ -using MongoDB.Bson; +using Etherna.MongODM.Core.Conventions; +using Etherna.MongODM.Core.Utility; +using MongoDB.Bson; using MongoDB.Bson.Serialization.Conventions; using System; using System.Collections.Generic; @@ -7,7 +9,7 @@ namespace Etherna.MongODM.Core.Serialization.Mapping { - public class DiscriminatorRegister : IDiscriminatorRegister + public class DiscriminatorRegister : FreezableConfig, IDiscriminatorRegister //TODO: Set to work as as FreezableConfig { // Fields. private readonly ReaderWriterLockSlim configLock = new(LockRecursionPolicy.SupportsRecursion); @@ -15,6 +17,22 @@ public class DiscriminatorRegister : IDiscriminatorRegister private readonly Dictionary> discriminators = new(); private readonly HashSet discriminatedTypes = new(); + private IDbContext dbContext = default!; + + // Constructor and initializer. + public void Initialize(IDbContext dbContext) + { + if (IsInitialized) + throw new InvalidOperationException("Instance already initialized"); + this.dbContext = dbContext; + + IsInitialized = true; + } + + + // Properties. + public bool IsInitialized { get; private set; } + // Methods. public void AddDiscriminator(Type type, BsonValue discriminator) { @@ -73,5 +91,54 @@ public void AddDiscriminatorConvention(Type type, IDiscriminatorConvention conve configLock.ExitWriteLock(); } } + + public IDiscriminatorConvention LookupDiscriminatorConvention(Type type) + { + configLock.EnterReadLock(); + try + { + if (discriminatorConventions.TryGetValue(type, out IDiscriminatorConvention convention)) + return convention; + } + finally + { + configLock.ExitReadLock(); + } + + configLock.EnterWriteLock(); + try + { + if (!discriminatorConventions.TryGetValue(type, out IDiscriminatorConvention convention)) + { + var typeInfo = type.GetTypeInfo(); + if (type == typeof(object)) + { + //if there is no convention registered for object register the default one + convention = new HierarchicalProxyTolerantDiscriminatorConvention("_t", dbContext.ProxyGenerator); + AddDiscriminatorConvention(typeof(object), convention); + } + else if (typeInfo.IsInterface) + { + // TODO: should convention for interfaces be inherited from parent interfaces? + convention = LookupDiscriminatorConvention(typeof(object)); + AddDiscriminatorConvention(type, convention); + } + else //type is not typeof(object), or interface + { + //inherit the discriminator convention from the closest parent that has one + convention = LookupDiscriminatorConvention(typeInfo.BaseType); + + //register the convention for current type + AddDiscriminatorConvention(type, convention); + } + } + + return convention; + } + finally + { + configLock.ExitWriteLock(); + } + } } } diff --git a/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs b/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs index 9f673756..48fce80e 100644 --- a/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs @@ -1,12 +1,14 @@ -using MongoDB.Bson; +using Etherna.MongODM.Core.Utility; +using MongoDB.Bson; using MongoDB.Bson.Serialization.Conventions; using System; namespace Etherna.MongODM.Core.Serialization.Mapping { - public interface IDiscriminatorRegister + public interface IDiscriminatorRegister : IDbContextInitializable, IFreezableConfig { void AddDiscriminator(Type type, BsonValue discriminator); void AddDiscriminatorConvention(Type type, IDiscriminatorConvention convention); + IDiscriminatorConvention LookupDiscriminatorConvention(Type type); } } \ No newline at end of file diff --git a/src/MongODM.Core/Serialization/Mapping/ModelMap.cs b/src/MongODM.Core/Serialization/Mapping/ModelMap.cs index a96ff0e3..e1496d46 100644 --- a/src/MongODM.Core/Serialization/Mapping/ModelMap.cs +++ b/src/MongODM.Core/Serialization/Mapping/ModelMap.cs @@ -117,12 +117,7 @@ public static IBsonSerializer GetDefaultSerializer(IDbContext db if (dbContext is null) throw new ArgumentNullException(nameof(dbContext)); - return new ModelMapSerializer( - dbContext.DbCache, - dbContext.Options.DocumentSemVer, - dbContext.Options.ModelMapVersion, - dbContext.SchemaRegister, - dbContext.SerializerModifierAccessor); + return new ModelMapSerializer(dbContext); } } diff --git a/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs index 7ada6e5b..e77325dd 100644 --- a/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs @@ -15,9 +15,6 @@ using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Options; using Etherna.MongODM.Core.ProxyModels; -using Etherna.MongODM.Core.Serialization.Mapping; -using Etherna.MongODM.Core.Serialization.Modifiers; -using Etherna.MongODM.Core.Utility; using MongoDB.Bson; using MongoDB.Bson.IO; using MongoDB.Bson.Serialization; @@ -35,26 +32,24 @@ public class ModelMapSerializer : { // Fields. private IDiscriminatorConvention _discriminatorConvention = default!; - private readonly IDbCache dbCache; private readonly BsonElement documentSemVerElement; + private readonly IDbContext dbContext; private readonly DocumentSemVerOptions documentSemVerOptions; private readonly ModelMapVersionOptions modelMapVersionOptions; - private readonly ISchemaRegister schemaRegister; - private readonly ISerializerModifierAccessor serializerModifierAccessor; // Constructor. public ModelMapSerializer( - IDbCache dbCache, - DocumentSemVerOptions documentSemVerOptions, - ModelMapVersionOptions modelMapVersionOptions, - ISchemaRegister schemaRegister, - ISerializerModifierAccessor serializerModifierAccessor) + IDbContext dbContext, + DocumentSemVerOptions? overrideDocumentSemVerOptions = null, + ModelMapVersionOptions? overrideModelMapVersionOptions = null) { - this.dbCache = dbCache ?? throw new ArgumentNullException(nameof(dbCache)); - this.documentSemVerOptions = documentSemVerOptions ?? throw new ArgumentNullException(nameof(documentSemVerOptions)); - this.modelMapVersionOptions = modelMapVersionOptions ?? throw new ArgumentNullException(nameof(modelMapVersionOptions)); - this.schemaRegister = schemaRegister ?? throw new ArgumentNullException(nameof(schemaRegister)); - this.serializerModifierAccessor = serializerModifierAccessor ?? throw new ArgumentNullException(nameof(serializerModifierAccessor)); + if (dbContext is null) + throw new ArgumentNullException(nameof(dbContext)); + + this.dbContext = dbContext; + + documentSemVerOptions = overrideDocumentSemVerOptions ?? dbContext.Options.DocumentSemVer; + modelMapVersionOptions = overrideModelMapVersionOptions ?? dbContext.Options.ModelMapVersion; documentSemVerElement = new BsonElement( documentSemVerOptions.ElementName, @@ -62,18 +57,18 @@ public ModelMapSerializer( } // Properties. - public IEnumerable AllChildClassMaps => schemaRegister.GetModelMapsSchema(typeof(TModel)) + public IEnumerable AllChildClassMaps => dbContext.SchemaRegister.GetModelMapsSchema(typeof(TModel)) .AllMapsDictionary.Values.Select(map => map.BsonClassMap); public BsonClassMapSerializer DefaultBsonClassMapSerializer => - (BsonClassMapSerializer)schemaRegister.GetModelMapsSchema(typeof(TModel)).ActiveMap.BsonClassMapSerializer; + (BsonClassMapSerializer)dbContext.SchemaRegister.GetModelMapsSchema(typeof(TModel)).ActiveMap.BsonClassMapSerializer; public IDiscriminatorConvention DiscriminatorConvention { get { if (_discriminatorConvention == null) - _discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(TModel)); + _discriminatorConvention = dbContext.DiscriminatorRegister.LookupDiscriminatorConvention(typeof(TModel)); return _discriminatorConvention; } } @@ -94,7 +89,7 @@ public override TModel Deserialize(BsonDeserializationContext context, BsonDeser // Find pre-deserialization informations. //get actual type and schema var actualType = DiscriminatorConvention.GetActualType(context.Reader, args.NominalType); - var actualTypeSchema = schemaRegister.GetModelMapsSchema(actualType); + var actualTypeSchema = dbContext.SchemaRegister.GetModelMapsSchema(actualType); //deserialize on document var bsonDocument = BsonDocumentSerializer.Instance.Deserialize(context, args); @@ -147,20 +142,20 @@ public override TModel Deserialize(BsonDeserializationContext context, BsonDeser } // Add model to cache. - if (!serializerModifierAccessor.IsNoCacheEnabled && + if (!dbContext.SerializerModifierAccessor.IsNoCacheEnabled && GetDocumentId(model, out var id, out _, out _) && id != null) { - if (dbCache.LoadedModels.ContainsKey(id)) + if (dbContext.DbCache.LoadedModels.ContainsKey(id)) { var fullModel = model; - model = (TModel)dbCache.LoadedModels[id]; + model = (TModel)dbContext.DbCache.LoadedModels[id]; if (((IReferenceable)model).IsSummary) ((IReferenceable)model).MergeFullModel(fullModel); } else { - dbCache.AddModel(id, (IEntityModel)model); + dbContext.DbCache.AddModel(id, (IEntityModel)model); } } @@ -201,7 +196,7 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati // Get default schema. var actualType = value.GetType(); - var modelMapsSchema = schemaRegister.GetModelMapsSchema(actualType); + var modelMapsSchema = dbContext.SchemaRegister.GetModelMapsSchema(actualType); // Serialize. modelMapsSchema.ActiveBsonClassMapSerializer.Serialize(localContext, args, value); @@ -215,7 +210,7 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati * don't have to replace it with the one wrong of the basic collection model type. */ if (!bsonDocument.Contains(modelMapVersionOptions.ElementName)) - bsonDocument.InsertAt(0, schemaRegister.GetActiveModelMapIdBsonElement(actualType)); + bsonDocument.InsertAt(0, dbContext.SchemaRegister.GetActiveModelMapIdBsonElement(actualType)); //add version if (documentSemVerOptions.WriteInDocuments && bsonWriter.IsRootDocument) diff --git a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs index f1d60732..6966ae7a 100644 --- a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs @@ -90,7 +90,7 @@ public IDiscriminatorConvention DiscriminatorConvention get { if (_discriminatorConvention == null) - _discriminatorConvention = BsonSerializer.LookupDiscriminatorConvention(typeof(TModelBase)); + _discriminatorConvention = dbContext.DiscriminatorRegister.LookupDiscriminatorConvention(typeof(TModelBase)); return _discriminatorConvention; } } diff --git a/test/MongODM.Core.Tests/ModelMapSerializerTest.cs b/test/MongODM.Core.Tests/ModelMapSerializerTest.cs index d1bd586a..04081659 100644 --- a/test/MongODM.Core.Tests/ModelMapSerializerTest.cs +++ b/test/MongODM.Core.Tests/ModelMapSerializerTest.cs @@ -78,6 +78,7 @@ public SerializationTestElement( // Fields. private readonly Mock dbCacheMock = new(); + private readonly Mock dbContextMock = new(); private readonly DocumentSemVerOptions documentSemVerOptions = new(); private readonly Mock modelMapsSchemaMock = new(); private readonly ModelMapVersionOptions modelMapVersionOptions = new(); @@ -90,6 +91,17 @@ public ModelMapSerializerTest() dbCacheMock.Setup(c => c.LoadedModels.ContainsKey(It.IsAny())) .Returns(() => false); + dbContextMock.Setup(c => c.DbCache) + .Returns(() => dbCacheMock.Object); + dbContextMock.Setup(c => c.Options.DocumentSemVer) + .Returns(() => documentSemVerOptions); + dbContextMock.Setup(c => c.Options.ModelMapVersion) + .Returns(() => modelMapVersionOptions); + dbContextMock.Setup(c => c.SchemaRegister) + .Returns(() => schemaRegisterMock.Object); + dbContextMock.Setup(c => c.SerializerModifierAccessor) + .Returns(() => serializerModifierAccessorMock.Object); + schemaRegisterMock.Setup(sr => sr.GetModelMapsSchema(typeof(FakeModel))) .Returns(() => modelMapsSchemaMock.Object); } @@ -137,12 +149,7 @@ public void Deserialize(DeserializationTestElement test) // Setup var bsonReader = new BsonDocumentReader(test.Document); var bsonClassMapSerializer = CreateBsonClassMapSerializer(); - var serializer = new ModelMapSerializer( - dbCacheMock.Object, - documentSemVerOptions, - modelMapVersionOptions, - schemaRegisterMock.Object, - serializerModifierAccessorMock.Object); + var serializer = new ModelMapSerializer(dbContextMock.Object); modelMapsSchemaMock.Setup(s => s.ActiveMap.BsonClassMapSerializer) .Returns(bsonClassMapSerializer); @@ -164,12 +171,7 @@ public void GetDocumentId() // Setup var model = new FakeModel { Id = "idVal" }; var bsonClassMapSerializer = CreateBsonClassMapSerializer(); - var serializer = new ModelMapSerializer( - dbCacheMock.Object, - documentSemVerOptions, - modelMapVersionOptions, - schemaRegisterMock.Object, - serializerModifierAccessorMock.Object); + var serializer = new ModelMapSerializer(dbContextMock.Object); modelMapsSchemaMock.Setup(s => s.ActiveMap.BsonClassMapSerializer) .Returns(bsonClassMapSerializer); @@ -200,12 +202,7 @@ public void GetMemberSerializationInfo() // Setup var memberName = nameof(FakeModel.StringProp); var bsonClassMapSerializer = CreateBsonClassMapSerializer(); - var serializer = new ModelMapSerializer( - dbCacheMock.Object, - documentSemVerOptions, - modelMapVersionOptions, - schemaRegisterMock.Object, - serializerModifierAccessorMock.Object); + var serializer = new ModelMapSerializer(dbContextMock.Object); modelMapsSchemaMock.Setup(s => s.ActiveMap.BsonClassMapSerializer) .Returns(bsonClassMapSerializer); @@ -293,12 +290,7 @@ public void Serialize(SerializationTestElement test) { // Setup var bsonClassMapSerializer = CreateBsonClassMapSerializer(); - var serializer = new ModelMapSerializer( - dbCacheMock.Object, - documentSemVerOptions, - modelMapVersionOptions, - schemaRegisterMock.Object, - serializerModifierAccessorMock.Object); + var serializer = new ModelMapSerializer(dbContextMock.Object); modelMapsSchemaMock.Setup(s => s.ActiveBsonClassMapSerializer) .Returns(bsonClassMapSerializer); @@ -327,12 +319,7 @@ public void SetDocumentId() var id = "idVal"; var model = new FakeModel(); var bsonClassMapSerializer = CreateBsonClassMapSerializer(); - var serializer = new ModelMapSerializer( - dbCacheMock.Object, - documentSemVerOptions, - modelMapVersionOptions, - schemaRegisterMock.Object, - serializerModifierAccessorMock.Object); + var serializer = new ModelMapSerializer(dbContextMock.Object); modelMapsSchemaMock.Setup(s => s.ActiveMap.BsonClassMapSerializer) .Returns(bsonClassMapSerializer); From fc9e7d2f05a771565883f10f05f367755578d82f Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Thu, 2 Dec 2021 01:23:26 +0100 Subject: [PATCH 30/78] Implementing serializer register --- src/MongODM.AspNetCore/DbDependencies.cs | 5 ++++- .../ServiceCollectionExtensions.cs | 2 ++ src/MongODM.Core/DbContext.cs | 21 ++++++++++++++++++- src/MongODM.Core/IDbContext.cs | 6 ++++++ src/MongODM.Core/IDbDependencies.cs | 2 ++ .../Mapping/DiscriminatorRegister.cs | 3 +-- .../Mapping/IDiscriminatorRegister.cs | 2 +- src/MongODM.Core/Utility/FreezableConfig.cs | 7 ++++++- 8 files changed, 42 insertions(+), 6 deletions(-) diff --git a/src/MongODM.AspNetCore/DbDependencies.cs b/src/MongODM.AspNetCore/DbDependencies.cs index 8cce70c7..bb9d2449 100644 --- a/src/MongODM.AspNetCore/DbDependencies.cs +++ b/src/MongODM.AspNetCore/DbDependencies.cs @@ -20,6 +20,7 @@ using Etherna.MongODM.Core.Serialization.Modifiers; using Etherna.MongODM.Core.Utility; using Microsoft.Extensions.Options; +using MongoDB.Bson.Serialization; using System; namespace Etherna.MongODM.AspNetCore @@ -27,6 +28,7 @@ namespace Etherna.MongODM.AspNetCore public class DbDependencies : IDbDependencies { public DbDependencies( + IBsonSerializerRegistry bsonSerializerRegistry, IDbCache dbCache, IDbMaintainer dbMaintainer, IDbMigrationManager dbContextMigrationManager, @@ -39,7 +41,7 @@ public DbDependencies( { if (mongODMOptions is null) throw new ArgumentNullException(nameof(mongODMOptions)); - + BsonSerializerRegistry = bsonSerializerRegistry; DbCache = dbCache; DbMaintainer = dbMaintainer; DbMigrationManager = dbContextMigrationManager; @@ -51,6 +53,7 @@ public DbDependencies( SerializerModifierAccessor = serializerModifierAccessor; } + public IBsonSerializerRegistry BsonSerializerRegistry { get; } public IDbCache DbCache { get; } public IDbMaintainer DbMaintainer { get; } public IDbMigrationManager DbMigrationManager { get; } diff --git a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs index 8f3a8140..1c80f4f6 100644 --- a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs +++ b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs @@ -24,6 +24,7 @@ using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; using MongoDB.Bson; +using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Conventions; using System; @@ -77,6 +78,7 @@ public static IMongODMConfiguration AddMongODM( * and passed to other with Initialize() method. This because otherwise inside * the same dbContext different components could have different instances of the same component. */ + services.TryAddTransient(); services.TryAddTransient(); services.TryAddTransient(); services.TryAddTransient(); diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index fe155bfe..75bbd7ea 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -12,7 +12,6 @@ // See the License for the specific language governing permissions and // limitations under the License. -using Etherna.MongODM.Core.Conventions; using Etherna.MongODM.Core.Domain.ModelMaps; using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Migration; @@ -23,6 +22,7 @@ using Etherna.MongODM.Core.Serialization.Mapping; using Etherna.MongODM.Core.Serialization.Modifiers; using Etherna.MongODM.Core.Utility; +using MongoDB.Bson.Serialization; using MongoDB.Driver; using MongoDB.Driver.Linq; using System; @@ -67,6 +67,7 @@ public async Task InitializeAsync( Options = options; ProxyGenerator = dependencies.ProxyGenerator; RepositoryRegister = dependencies.RepositoryRegister; + SerializerRegister = dependencies.BsonSerializerRegistry; SchemaRegister = dependencies.SchemaRegister; SerializerModifierAccessor = dependencies.SerializerModifierAccessor; @@ -79,6 +80,7 @@ public async Task InitializeAsync( DbMigrationManager.Initialize(this); RepositoryRegister.Initialize(this); SchemaRegister.Initialize(this); + CreateSerializerRegistry(); // Initialize repositories. foreach (var repository in RepositoryRegister.ModelRepositoryMap.Values) @@ -124,6 +126,7 @@ public async Task InitializeAsync( public IDbContextOptions Options { get; private set; } = default!; public IProxyGenerator ProxyGenerator { get; private set; } = default!; public IRepositoryRegister RepositoryRegister { get; private set; } = default!; + public IBsonSerializerRegistry SerializerRegister { get; private set; } = default!; public ISchemaRegister SchemaRegister { get; private set; } = default!; public ISerializerModifierAccessor SerializerModifierAccessor { get; private set; } = default!; @@ -207,5 +210,21 @@ public Task StartSessionAsync(CancellationToken cancellati // Protected methods. protected virtual Task SeedAsync() => Task.CompletedTask; + + // Helpers. + private void CreateSerializerRegistry() + { + var register = (BsonSerializerRegistry)SerializerRegister; + __typeMappingSerializationProvider = new TypeMappingSerializationProvider(); + + // order matters. It's in reverse order of how they'll get consumed + register.RegisterSerializationProvider(new BsonClassMapSerializationProvider()); + register.RegisterSerializationProvider(new DiscriminatedInterfaceSerializationProvider()); + register.RegisterSerializationProvider(new CollectionsSerializationProvider()); + register.RegisterSerializationProvider(new PrimitiveSerializationProvider()); + register.RegisterSerializationProvider(new AttributedSerializationProvider()); + register.RegisterSerializationProvider(__typeMappingSerializationProvider); + register.RegisterSerializationProvider(new BsonObjectModelSerializationProvider()); + } } } \ No newline at end of file diff --git a/src/MongODM.Core/IDbContext.cs b/src/MongODM.Core/IDbContext.cs index faa359e3..dab50ab8 100644 --- a/src/MongODM.Core/IDbContext.cs +++ b/src/MongODM.Core/IDbContext.cs @@ -21,6 +21,7 @@ using Etherna.MongODM.Core.Serialization.Mapping; using Etherna.MongODM.Core.Serialization.Modifiers; using Etherna.MongODM.Core.Utility; +using MongoDB.Bson.Serialization; using MongoDB.Driver; using System.Collections.Generic; using System.Threading; @@ -99,6 +100,11 @@ public interface IDbContext /// IRepositoryRegister RepositoryRegister { get; } + /// + /// Local instance of a serializer register. + /// + IBsonSerializerRegistry SerializerRegister { get; } + /// /// Register for model serialization and schema information. /// diff --git a/src/MongODM.Core/IDbDependencies.cs b/src/MongODM.Core/IDbDependencies.cs index d6afc4cf..374dc8e7 100644 --- a/src/MongODM.Core/IDbDependencies.cs +++ b/src/MongODM.Core/IDbDependencies.cs @@ -17,11 +17,13 @@ using Etherna.MongODM.Core.Serialization.Mapping; using Etherna.MongODM.Core.Serialization.Modifiers; using Etherna.MongODM.Core.Utility; +using MongoDB.Bson.Serialization; namespace Etherna.MongODM.Core { public interface IDbDependencies { + IBsonSerializerRegistry BsonSerializerRegistry { get; } IDbCache DbCache { get; } IDbMaintainer DbMaintainer { get; } IDbMigrationManager DbMigrationManager { get; } diff --git a/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs index 6c27ce44..214f79df 100644 --- a/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs @@ -1,5 +1,4 @@ using Etherna.MongODM.Core.Conventions; -using Etherna.MongODM.Core.Utility; using MongoDB.Bson; using MongoDB.Bson.Serialization.Conventions; using System; @@ -9,7 +8,7 @@ namespace Etherna.MongODM.Core.Serialization.Mapping { - public class DiscriminatorRegister : FreezableConfig, IDiscriminatorRegister //TODO: Set to work as as FreezableConfig + public class DiscriminatorRegister : IDiscriminatorRegister { // Fields. private readonly ReaderWriterLockSlim configLock = new(LockRecursionPolicy.SupportsRecursion); diff --git a/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs b/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs index 48fce80e..56bf46ca 100644 --- a/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs @@ -5,7 +5,7 @@ namespace Etherna.MongODM.Core.Serialization.Mapping { - public interface IDiscriminatorRegister : IDbContextInitializable, IFreezableConfig + public interface IDiscriminatorRegister : IDbContextInitializable { void AddDiscriminator(Type type, BsonValue discriminator); void AddDiscriminatorConvention(Type type, IDiscriminatorConvention convention); diff --git a/src/MongODM.Core/Utility/FreezableConfig.cs b/src/MongODM.Core/Utility/FreezableConfig.cs index 5369c4dc..d14748bb 100644 --- a/src/MongODM.Core/Utility/FreezableConfig.cs +++ b/src/MongODM.Core/Utility/FreezableConfig.cs @@ -76,12 +76,17 @@ public void Freeze() } // Protected methods. - protected void ExecuteConfigAction(Action configAction) => + protected void ExecuteConfigAction(Action configAction) + { + if (configAction is null) + throw new ArgumentNullException(nameof(configAction)); + ExecuteConfigAction(() => { configAction(); return 0; }); + } protected TReturn ExecuteConfigAction(Func configAction) { From 8bc78412605c58597e3862d6a9c44e25f7d90e93 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Fri, 3 Dec 2021 00:25:04 +0100 Subject: [PATCH 31/78] Cleaned SerializerRegister configuration --- src/MongODM.Core/DbContext.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index 75bbd7ea..e0d7ba54 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -80,7 +80,7 @@ public async Task InitializeAsync( DbMigrationManager.Initialize(this); RepositoryRegister.Initialize(this); SchemaRegister.Initialize(this); - CreateSerializerRegistry(); + InitializeSerializerRegister(); // Initialize repositories. foreach (var repository in RepositoryRegister.ModelRepositoryMap.Values) @@ -212,18 +212,15 @@ protected virtual Task SeedAsync() => Task.CompletedTask; // Helpers. - private void CreateSerializerRegistry() + private void InitializeSerializerRegister() { var register = (BsonSerializerRegistry)SerializerRegister; - __typeMappingSerializationProvider = new TypeMappingSerializationProvider(); - // order matters. It's in reverse order of how they'll get consumed - register.RegisterSerializationProvider(new BsonClassMapSerializationProvider()); + //order matters. It's in reverse order of how they'll get consumed register.RegisterSerializationProvider(new DiscriminatedInterfaceSerializationProvider()); register.RegisterSerializationProvider(new CollectionsSerializationProvider()); register.RegisterSerializationProvider(new PrimitiveSerializationProvider()); register.RegisterSerializationProvider(new AttributedSerializationProvider()); - register.RegisterSerializationProvider(__typeMappingSerializationProvider); register.RegisterSerializationProvider(new BsonObjectModelSerializationProvider()); } } From e8b460ebea7e4512dee0a4056544c48762bd7d84 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sat, 4 Dec 2021 00:50:37 +0100 Subject: [PATCH 32/78] Implementing HierarchicalProxyTolerantDiscriminatorConvention without static references Updated ExtraElementsSerializer for remove static references --- ...calProxyTolerantDiscriminatorConvention.cs | 90 +++++++++++++++++-- src/MongODM.Core/DbContext.cs | 17 ++-- .../Mapping/DiscriminatorRegister.cs | 2 +- .../Mapping/IDiscriminatorRegister.cs | 3 +- .../Serialization/Mapping/ISchemaRegister.cs | 7 ++ .../Serialization/Mapping/SchemaRegister.cs | 29 +++++- .../Serializers/ExtraElementsSerializer.cs | 24 +++-- 7 files changed, 142 insertions(+), 30 deletions(-) diff --git a/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs b/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs index 20f51272..de5e2fdd 100644 --- a/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs +++ b/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs @@ -12,29 +12,101 @@ // See the License for the specific language governing permissions and // limitations under the License. -using Etherna.MongODM.Core.ProxyModels; using MongoDB.Bson; +using MongoDB.Bson.IO; +using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Conventions; using System; +using System.Collections.Generic; +using System.Linq; namespace Etherna.MongODM.Core.Conventions { - public class HierarchicalProxyTolerantDiscriminatorConvention : HierarchicalDiscriminatorConvention + public class HierarchicalProxyTolerantDiscriminatorConvention : IDiscriminatorConvention { // Fields. - private readonly IProxyGenerator proxyGenerator; + private readonly IDbContext dbContext; // Constructors. public HierarchicalProxyTolerantDiscriminatorConvention( - string elementName, - IProxyGenerator proxyGenerator) - : base(elementName) + IDbContext dbContext, + string elementName) { - this.proxyGenerator = proxyGenerator ?? throw new ArgumentNullException(nameof(proxyGenerator)); + this.dbContext = dbContext; + + ElementName = elementName ?? throw new ArgumentNullException(nameof(elementName)); + if (elementName.IndexOf('\0') != -1) + throw new ArgumentException("Element names cannot contain nulls.", nameof(elementName)); } + public string ElementName { get; } + // Methods. - public override BsonValue GetDiscriminator(Type nominalType, Type actualType) => - base.GetDiscriminator(nominalType, proxyGenerator.PurgeProxyType(actualType)); + public Type GetActualType(IBsonReader bsonReader, Type nominalType) + { + // the BsonReader is sitting at the value whose actual type needs to be found + var bsonType = bsonReader.GetCurrentBsonType(); + if (bsonType == BsonType.Document) + { + // ensure KnownTypes of nominalType are registered (so IsTypeDiscriminated returns correct answer) + BsonSerializer.EnsureKnownTypesAreRegistered(nominalType); + + // we can skip looking for a discriminator if nominalType has no discriminated sub types + if (BsonSerializer.IsTypeDiscriminated(nominalType)) + { + var bookmark = bsonReader.GetBookmark(); + bsonReader.ReadStartDocument(); + var actualType = nominalType; + if (bsonReader.FindElement(ElementName)) + { + var context = BsonDeserializationContext.CreateRoot(bsonReader); + var discriminator = BsonValueSerializer.Instance.Deserialize(context); + if (discriminator.IsBsonArray) + { + discriminator = discriminator.AsBsonArray.Last(); // last item is leaf class discriminator + } + actualType = BsonSerializer.LookupActualType(nominalType, discriminator); + } + bsonReader.ReturnToBookmark(bookmark); + return actualType; + } + } + + return nominalType; + } + + /// + /// Gets the discriminator value for an actual type. + /// + /// The nominal type. + /// The actual type. + /// The discriminator value. + public BsonValue? GetDiscriminator(Type nominalType, Type actualType) + { + // Remove proxy type. + actualType = dbContext.ProxyGenerator.PurgeProxyType(actualType); + + // Find active class map for model type. + var classMap = dbContext.SchemaRegister.GetActiveClassMap(actualType); + + // Get discriminator from class map. + if (actualType != nominalType || classMap.DiscriminatorIsRequired || classMap.HasRootClass) + { + if (classMap.HasRootClass && !classMap.IsRootClass) + { + var values = new List(); + for (; !classMap.IsRootClass; classMap = classMap.BaseClassMap) + { + values.Add(classMap.Discriminator); + } + values.Add(classMap.Discriminator); //add the root class's discriminator + return new BsonArray(values.Reverse()); //reverse to put leaf class last + } + else + return classMap.Discriminator; + } + + return null; + } } } diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index e0d7ba54..97684e2e 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -37,6 +37,7 @@ namespace Etherna.MongODM.Core public abstract class DbContext : IDbContext, IDbContextBuilder { // Fields. + private BsonSerializerRegistry _serializerRegister = default!; private bool isInitialized; // Constructor and initializer. @@ -67,9 +68,9 @@ public async Task InitializeAsync( Options = options; ProxyGenerator = dependencies.ProxyGenerator; RepositoryRegister = dependencies.RepositoryRegister; - SerializerRegister = dependencies.BsonSerializerRegistry; SchemaRegister = dependencies.SchemaRegister; SerializerModifierAccessor = dependencies.SerializerModifierAccessor; + _serializerRegister = (BsonSerializerRegistry)dependencies.BsonSerializerRegistry; // Initialize MongoDB driver. Client = new MongoClient(options.ConnectionString); @@ -126,7 +127,7 @@ public async Task InitializeAsync( public IDbContextOptions Options { get; private set; } = default!; public IProxyGenerator ProxyGenerator { get; private set; } = default!; public IRepositoryRegister RepositoryRegister { get; private set; } = default!; - public IBsonSerializerRegistry SerializerRegister { get; private set; } = default!; + public IBsonSerializerRegistry SerializerRegister => _serializerRegister; public ISchemaRegister SchemaRegister { get; private set; } = default!; public ISerializerModifierAccessor SerializerModifierAccessor { get; private set; } = default!; @@ -214,14 +215,12 @@ protected virtual Task SeedAsync() => // Helpers. private void InitializeSerializerRegister() { - var register = (BsonSerializerRegistry)SerializerRegister; - //order matters. It's in reverse order of how they'll get consumed - register.RegisterSerializationProvider(new DiscriminatedInterfaceSerializationProvider()); - register.RegisterSerializationProvider(new CollectionsSerializationProvider()); - register.RegisterSerializationProvider(new PrimitiveSerializationProvider()); - register.RegisterSerializationProvider(new AttributedSerializationProvider()); - register.RegisterSerializationProvider(new BsonObjectModelSerializationProvider()); + _serializerRegister.RegisterSerializationProvider(new DiscriminatedInterfaceSerializationProvider()); + _serializerRegister.RegisterSerializationProvider(new CollectionsSerializationProvider()); + _serializerRegister.RegisterSerializationProvider(new PrimitiveSerializationProvider()); + _serializerRegister.RegisterSerializationProvider(new AttributedSerializationProvider()); + _serializerRegister.RegisterSerializationProvider(new BsonObjectModelSerializationProvider()); } } } \ No newline at end of file diff --git a/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs index 214f79df..2f7b7a2a 100644 --- a/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs @@ -113,7 +113,7 @@ public IDiscriminatorConvention LookupDiscriminatorConvention(Type type) if (type == typeof(object)) { //if there is no convention registered for object register the default one - convention = new HierarchicalProxyTolerantDiscriminatorConvention("_t", dbContext.ProxyGenerator); + convention = new HierarchicalProxyTolerantDiscriminatorConvention(dbContext, "_t"); AddDiscriminatorConvention(typeof(object), convention); } else if (typeInfo.IsInterface) diff --git a/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs b/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs index 56bf46ca..231fab45 100644 --- a/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs @@ -1,5 +1,4 @@ -using Etherna.MongODM.Core.Utility; -using MongoDB.Bson; +using MongoDB.Bson; using MongoDB.Bson.Serialization.Conventions; using System; diff --git a/src/MongODM.Core/Serialization/Mapping/ISchemaRegister.cs b/src/MongODM.Core/Serialization/Mapping/ISchemaRegister.cs index 4f36761a..aab7174a 100644 --- a/src/MongODM.Core/Serialization/Mapping/ISchemaRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/ISchemaRegister.cs @@ -68,6 +68,13 @@ IModelMapsSchemaBuilder AddModelMapsSchema( ModelMap activeModelMap) where TModel : class; + /// + /// Get active class map from schemas, or create a default classMap for model type + /// + /// The model type + /// The active model map + BsonClassMap GetActiveClassMap(Type modelType); + /// /// Return bson element for represent a model map id /// diff --git a/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs b/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs index e275cd61..bcd5a8fb 100644 --- a/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs @@ -19,6 +19,7 @@ using MongoDB.Bson; using MongoDB.Bson.Serialization; using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -33,6 +34,7 @@ public class SchemaRegister : FreezableConfig, ISchemaRegister private readonly Dictionary _schemas = new(); private readonly Dictionary activeModelMapIdBsonElement = new(); + private readonly ConcurrentDictionary defaultClassMapsCache = new(); private readonly Dictionary> memberInfoToMemberMapsDictionary = new(); private readonly Dictionary> modelTypeToReferencedIdMemberMapsDictionary = new(); @@ -105,6 +107,29 @@ public IModelMapsSchemaBuilder AddModelMapsSchema( return modelSchemaConfiguration; }); + public BsonClassMap GetActiveClassMap(Type modelType) + { + // If a schema is registered. + if (_schemas.ContainsKey(modelType) && + _schemas[modelType] is IModelMapsSchema modelMapSchema) + return modelMapSchema.ActiveMap.BsonClassMap; + + // If we don't have a model schema, look for a default classmap, or create it. + if (defaultClassMapsCache.ContainsKey(modelType)) + return defaultClassMapsCache[modelType]; + + var classMapDefinition = typeof(BsonClassMap<>); + var classMapType = classMapDefinition.MakeGenericType(modelType); + var classMap = (BsonClassMap)Activator.CreateInstance(classMapType); + classMap.AutoMap(); + + // Register classMap (if doesn't exist) with discriminator. + defaultClassMapsCache.TryAdd(modelType, classMap); + dbContext.DiscriminatorRegister.AddDiscriminator(modelType, classMap.Discriminator); + + return classMap; + } + public BsonElement GetActiveModelMapIdBsonElement(Type modelType) { if (modelType is null) @@ -144,7 +169,7 @@ public IModelMapsSchema GetModelMapsSchema(Type modelType) if (modelType is null) throw new ArgumentNullException(nameof(modelType)); if (!_schemas.ContainsKey(modelType)) - throw new InvalidOperationException(modelType.Name + " schema is not registered"); + throw new KeyNotFoundException(modelType.Name + " schema is not registered"); var schema = _schemas[modelType]; @@ -199,7 +224,7 @@ protected override void FreezeAction() // Register active serializer. if (schema.ActiveSerializer != null) - BsonSerializer.RegisterSerializer(schema.ModelType, schema.ActiveSerializer); + ((BsonSerializerRegistry)dbContext.SerializerRegister).RegisterSerializer(schema.ModelType, schema.ActiveSerializer); // Register discriminators for all bson class maps. if (schema is IModelMapsSchema modelMapsSchema) diff --git a/src/MongODM.Core/Serialization/Serializers/ExtraElementsSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ExtraElementsSerializer.cs index 9e4d969a..2cd87305 100644 --- a/src/MongODM.Core/Serialization/Serializers/ExtraElementsSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ExtraElementsSerializer.cs @@ -21,10 +21,21 @@ namespace Etherna.MongODM.Core.Serialization.Serializers { + /// + /// Utility serializer used for help into document migration scripts. + /// public class ExtraElementsSerializer : SerializerBase { - private static ExtraElementsSerializer Instance { get; } = new ExtraElementsSerializer(); + // Fields. + private readonly IDbContext dbContext; + // Constructor. + public ExtraElementsSerializer(IDbContext dbContext) + { + this.dbContext = dbContext; + } + + // Methods. public override void Serialize(BsonSerializationContext context, BsonSerializationArgs args, object value) { if (context is null) @@ -51,13 +62,12 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati } else { - BsonSerializer.Serialize(context.Writer, value); + var serializer = dbContext.SerializerRegister.GetSerializer(); + serializer.Serialize(context, value); } } - // Static methods. - - public static TValue DeserializeValue( + public TValue DeserializeValue( object extraElements, IBsonSerializer? serializer = null) { @@ -71,13 +81,13 @@ public static TValue DeserializeValue( serializationContext.Writer.WriteStartDocument(); serializationContext.Writer.WriteName("container"); - Instance.Serialize(serializationContext, extraElements); + this.Serialize(serializationContext, extraElements); serializationContext.Writer.WriteEndDocument(); // Lookup for a serializer. if (serializer == null) { - serializer = BsonSerializer.LookupSerializer(); + serializer = dbContext.SerializerRegister.GetSerializer(); } // Deserialize. From 761f1c08ad66181eb8b71bd5e4e9a9c5dce4ba22 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sun, 5 Dec 2021 16:39:18 +0100 Subject: [PATCH 33/78] Removed static references from HierarchicalProxyTolerantDiscriminatorConvention --- .../Properties/launchSettings.json | 2 +- ...calProxyTolerantDiscriminatorConvention.cs | 17 ++++---- .../Mapping/DiscriminatorRegister.cs | 42 +++++++++++++++++++ .../Mapping/IDiscriminatorRegister.cs | 17 ++++++++ 4 files changed, 69 insertions(+), 9 deletions(-) diff --git a/samples/AspNetCoreSample/Properties/launchSettings.json b/samples/AspNetCoreSample/Properties/launchSettings.json index e79b8d8e..34683463 100644 --- a/samples/AspNetCoreSample/Properties/launchSettings.json +++ b/samples/AspNetCoreSample/Properties/launchSettings.json @@ -3,7 +3,7 @@ "windowsAuthentication": false, "anonymousAuthentication": true, "iisExpress": { - "applicationUrl": "http://localhost:57677", + "applicationUrl": "http://localhost:47677", "sslPort": 44384 } }, diff --git a/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs b/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs index de5e2fdd..81a79d4d 100644 --- a/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs +++ b/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs @@ -16,6 +16,7 @@ using MongoDB.Bson.IO; using MongoDB.Bson.Serialization; using MongoDB.Bson.Serialization.Conventions; +using MongoDB.Bson.Serialization.Serializers; using System; using System.Collections.Generic; using System.Linq; @@ -44,15 +45,15 @@ public HierarchicalProxyTolerantDiscriminatorConvention( // Methods. public Type GetActualType(IBsonReader bsonReader, Type nominalType) { - // the BsonReader is sitting at the value whose actual type needs to be found + if (bsonReader is null) + throw new ArgumentNullException(nameof(bsonReader)); + + //the BsonReader is sitting at the value whose actual type needs to be found var bsonType = bsonReader.GetCurrentBsonType(); if (bsonType == BsonType.Document) { - // ensure KnownTypes of nominalType are registered (so IsTypeDiscriminated returns correct answer) - BsonSerializer.EnsureKnownTypesAreRegistered(nominalType); - - // we can skip looking for a discriminator if nominalType has no discriminated sub types - if (BsonSerializer.IsTypeDiscriminated(nominalType)) + //we can skip looking for a discriminator if nominalType has no discriminated sub types + if (dbContext.DiscriminatorRegister.IsTypeDiscriminated(nominalType)) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); @@ -63,9 +64,9 @@ public Type GetActualType(IBsonReader bsonReader, Type nominalType) var discriminator = BsonValueSerializer.Instance.Deserialize(context); if (discriminator.IsBsonArray) { - discriminator = discriminator.AsBsonArray.Last(); // last item is leaf class discriminator + discriminator = discriminator.AsBsonArray.Last(); //last item is leaf class discriminator } - actualType = BsonSerializer.LookupActualType(nominalType, discriminator); + actualType = dbContext.DiscriminatorRegister.LookupActualType(nominalType, discriminator); } bsonReader.ReturnToBookmark(bookmark); return actualType; diff --git a/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs index 2f7b7a2a..4e28ab82 100644 --- a/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs @@ -91,6 +91,48 @@ public void AddDiscriminatorConvention(Type type, IDiscriminatorConvention conve } } + public bool IsTypeDiscriminated(Type type) + { + var typeInfo = type.GetTypeInfo(); + return typeInfo.IsInterface || discriminatedTypes.Contains(type); + } + + public Type LookupActualType(Type nominalType, BsonValue? discriminator) + { + if (discriminator == null) + return nominalType; + + configLock.EnterReadLock(); + try + { + Type? actualType = null; + + var nominalTypeInfo = nominalType.GetTypeInfo(); + if (discriminators.TryGetValue(discriminator, out HashSet hashSet)) + { + foreach (var type in hashSet) + { + if (nominalTypeInfo.IsAssignableFrom(type)) + { + if (actualType == null) + actualType = type; + else + throw new BsonSerializationException($"Ambiguous discriminator '{discriminator}'."); + } + } + } + + if (actualType == null) + throw new BsonSerializationException($"Unknown discriminator value '{discriminator}'."); + + return actualType; + } + finally + { + configLock.ExitReadLock(); + } + } + public IDiscriminatorConvention LookupDiscriminatorConvention(Type type) { configLock.EnterReadLock(); diff --git a/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs b/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs index 231fab45..e0c52722 100644 --- a/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs @@ -7,7 +7,24 @@ namespace Etherna.MongODM.Core.Serialization.Mapping public interface IDiscriminatorRegister : IDbContextInitializable { void AddDiscriminator(Type type, BsonValue discriminator); + void AddDiscriminatorConvention(Type type, IDiscriminatorConvention convention); + + /// + /// Returns whether the given type has any discriminators registered for any of its subclasses. + /// + /// A Type. + /// True if the type is discriminated. + bool IsTypeDiscriminated(Type type); + + /// + /// Looks up the actual type of an object to be deserialized. + /// + /// The nominal type of the object. + /// The discriminator. + /// The actual type of the object. + Type LookupActualType(Type nominalType, BsonValue? discriminator); + IDiscriminatorConvention LookupDiscriminatorConvention(Type type); } } \ No newline at end of file From f87bc1833f281f7d8c81e3a95f1c9efdc4eee65a Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Tue, 7 Dec 2021 00:30:50 +0100 Subject: [PATCH 34/78] Migrated to Etherna fork of MongoDB drivers --- .../AspNetCoreSample/Models/ModelMaps/ModelBaseMap.cs | 6 +++--- samples/AspNetCoreSample/Pages/Index.cshtml.cs | 2 +- src/MongODM.AspNetCore/ServiceCollectionExtensions.cs | 6 +++--- ...HierarchicalProxyTolerantDiscriminatorConvention.cs | 4 ++-- src/MongODM.Core/DbContext.cs | 4 ++-- src/MongODM.Core/Domain/ModelMaps/ModelBaseMap.cs | 6 +++--- src/MongODM.Core/Extensions/BsonClassMapExtensions.cs | 2 +- src/MongODM.Core/Extensions/BsonMemberMapExtensions.cs | 2 +- src/MongODM.Core/Extensions/EnumerableExtensions.cs | 2 +- src/MongODM.Core/IDbContext.cs | 2 +- src/MongODM.Core/Migration/DocumentMigration.cs | 2 +- src/MongODM.Core/MongODM.Core.csproj | 4 ++-- src/MongODM.Core/Repositories/CollectionRepository.cs | 6 +++--- .../Repositories/CollectionRepositoryOptions.cs | 2 +- src/MongODM.Core/Repositories/GridFSRepository.cs | 6 +++--- .../Repositories/GridFSRepositoryOptions.cs | 2 +- src/MongODM.Core/Repositories/ICollectionRepository.cs | 4 ++-- src/MongODM.Core/Repositories/IGridFSRepository.cs | 2 +- .../Serialization/ExtendedBsonDocumentWriter.cs | 4 ++-- src/MongODM.Core/Serialization/Mapping/IModelMap.cs | 2 +- .../Serialization/Mapping/ISchemaRegister.cs | 4 ++-- .../Serialization/Mapping/MemberDependency.cs | 2 +- src/MongODM.Core/Serialization/Mapping/ModelMap.cs | 2 +- .../Serialization/Mapping/OwnedBsonMemberMap.cs | 2 +- .../Serialization/Mapping/SchemaRegister.cs | 4 ++-- .../Mapping/Schemas/CustomSerializerSchema.cs | 2 +- .../Serialization/Mapping/Schemas/IModelMapsSchema.cs | 2 +- .../Mapping/Schemas/IModelMapsSchemaBuilder.cs | 2 +- .../Schemas/IReferenceModelMapsSchemaBuilder.cs | 2 +- .../Serialization/Mapping/Schemas/ISchema.cs | 2 +- .../Serialization/Mapping/Schemas/ModelMapsSchema.cs | 2 +- .../Mapping/Schemas/ModelMapsSchemaBase.cs | 2 +- .../Mapping/Schemas/ReferenceModelMapsSchema.cs | 2 +- .../Serialization/Mapping/Schemas/SchemaBase.cs | 2 +- src/MongODM.Core/Serialization/SemanticVersion.cs | 2 +- .../Serialization/Serializers/DictionarySerializer.cs | 6 +++--- .../Serialization/Serializers/EnumerableSerializer.cs | 4 ++-- .../Serializers/ExtraElementsSerializer.cs | 8 ++++---- .../Serialization/Serializers/GeoPointSerializer.cs | 8 ++++---- .../Serializers/HexToBinaryDataSerializer.cs | 6 +++--- .../Serializers/IModelMapsContainerSerializer.cs | 2 +- .../Serialization/Serializers/ModelMapSerializer.cs | 10 +++++----- .../Serializers/ReadOnlyDictionarySerializer.cs | 6 +++--- .../Serialization/Serializers/ReferenceSerializer.cs | 10 +++++----- .../Serializers/ReferenceSerializerAdapter.cs | 4 ++-- .../Serializers/ReferenceSerializerConfiguration.cs | 4 ++-- src/MongODM.Core/Tasks/UpdateDocDependenciesTask.cs | 2 +- src/MongODM.Core/Utility/DbMaintainer.cs | 2 +- src/MongODM.Core/Utility/DbMigrationManager.cs | 4 ++-- test/MongODM.Core.Tests/ModelMapSerializerTest.cs | 6 +++--- 50 files changed, 93 insertions(+), 93 deletions(-) diff --git a/samples/AspNetCoreSample/Models/ModelMaps/ModelBaseMap.cs b/samples/AspNetCoreSample/Models/ModelMaps/ModelBaseMap.cs index 44ab0a22..3d6bcbc7 100644 --- a/samples/AspNetCoreSample/Models/ModelMaps/ModelBaseMap.cs +++ b/samples/AspNetCoreSample/Models/ModelMaps/ModelBaseMap.cs @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson; +using Etherna.MongoDB.Bson.Serialization.IdGenerators; +using Etherna.MongoDB.Bson.Serialization.Serializers; using Etherna.MongODM.Core; using Etherna.MongODM.Core.Serialization; -using MongoDB.Bson; -using MongoDB.Bson.Serialization.IdGenerators; -using MongoDB.Bson.Serialization.Serializers; namespace Etherna.MongODM.AspNetCoreSample.Models.ModelMaps { diff --git a/samples/AspNetCoreSample/Pages/Index.cshtml.cs b/samples/AspNetCoreSample/Pages/Index.cshtml.cs index 8668856c..ee9191fa 100644 --- a/samples/AspNetCoreSample/Pages/Index.cshtml.cs +++ b/samples/AspNetCoreSample/Pages/Index.cshtml.cs @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Driver; using Etherna.MongODM.AspNetCoreSample.Models; using Etherna.MongODM.AspNetCoreSample.Persistence; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.RazorPages; -using MongoDB.Driver; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; diff --git a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs index 08876167..5cbe87ae 100644 --- a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs +++ b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs @@ -13,6 +13,9 @@ // limitations under the License. using Etherna.ExecContext.AspNetCore; +using Etherna.MongoDB.Bson; +using Etherna.MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization.Conventions; using Etherna.MongODM.Core; using Etherna.MongODM.Core.Conventions; using Etherna.MongODM.Core.Domain.Models; @@ -25,9 +28,6 @@ using Etherna.MongODM.Core.Utility; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection.Extensions; -using MongoDB.Bson; -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Conventions; using System; namespace Etherna.MongODM.AspNetCore diff --git a/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs b/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs index 20f51272..4de55550 100644 --- a/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs +++ b/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson; +using Etherna.MongoDB.Bson.Serialization.Conventions; using Etherna.MongODM.Core.ProxyModels; -using MongoDB.Bson; -using MongoDB.Bson.Serialization.Conventions; using System; namespace Etherna.MongODM.Core.Conventions diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index d0d35409..c1770724 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Driver; +using Etherna.MongoDB.Driver.Linq; using Etherna.MongODM.Core.Domain.ModelMaps; using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Migration; @@ -22,8 +24,6 @@ using Etherna.MongODM.Core.Serialization.Mapping; using Etherna.MongODM.Core.Serialization.Modifiers; using Etherna.MongODM.Core.Utility; -using MongoDB.Driver; -using MongoDB.Driver.Linq; using System; using System.Collections.Generic; using System.Linq; diff --git a/src/MongODM.Core/Domain/ModelMaps/ModelBaseMap.cs b/src/MongODM.Core/Domain/ModelMaps/ModelBaseMap.cs index 1f9a6f10..64250e43 100644 --- a/src/MongODM.Core/Domain/ModelMaps/ModelBaseMap.cs +++ b/src/MongODM.Core/Domain/ModelMaps/ModelBaseMap.cs @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson; +using Etherna.MongoDB.Bson.Serialization.IdGenerators; +using Etherna.MongoDB.Bson.Serialization.Serializers; using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Serialization; -using MongoDB.Bson; -using MongoDB.Bson.Serialization.IdGenerators; -using MongoDB.Bson.Serialization.Serializers; namespace Etherna.MongODM.Core.Domain.ModelMaps { diff --git a/src/MongODM.Core/Extensions/BsonClassMapExtensions.cs b/src/MongODM.Core/Extensions/BsonClassMapExtensions.cs index 6834a3a1..bd863112 100644 --- a/src/MongODM.Core/Extensions/BsonClassMapExtensions.cs +++ b/src/MongODM.Core/Extensions/BsonClassMapExtensions.cs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson.Serialization; using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Serialization.Serializers; -using MongoDB.Bson.Serialization; using System; using System.Linq.Expressions; using System.Reflection; diff --git a/src/MongODM.Core/Extensions/BsonMemberMapExtensions.cs b/src/MongODM.Core/Extensions/BsonMemberMapExtensions.cs index ffdfe687..bb1db4b1 100644 --- a/src/MongODM.Core/Extensions/BsonMemberMapExtensions.cs +++ b/src/MongODM.Core/Extensions/BsonMemberMapExtensions.cs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization; using System; namespace Etherna.MongODM.Core.Extensions diff --git a/src/MongODM.Core/Extensions/EnumerableExtensions.cs b/src/MongODM.Core/Extensions/EnumerableExtensions.cs index 190d212e..1a8d531f 100644 --- a/src/MongODM.Core/Extensions/EnumerableExtensions.cs +++ b/src/MongODM.Core/Extensions/EnumerableExtensions.cs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Driver.Linq; +using Etherna.MongoDB.Driver.Linq; using System; using System.Collections.Generic; using System.Linq; diff --git a/src/MongODM.Core/IDbContext.cs b/src/MongODM.Core/IDbContext.cs index 0c179b1b..084b5a0c 100644 --- a/src/MongODM.Core/IDbContext.cs +++ b/src/MongODM.Core/IDbContext.cs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Driver; using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Migration; using Etherna.MongODM.Core.Options; @@ -21,7 +22,6 @@ using Etherna.MongODM.Core.Serialization.Mapping; using Etherna.MongODM.Core.Serialization.Modifiers; using Etherna.MongODM.Core.Utility; -using MongoDB.Driver; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; diff --git a/src/MongODM.Core/Migration/DocumentMigration.cs b/src/MongODM.Core/Migration/DocumentMigration.cs index e81e37da..713cd2bd 100644 --- a/src/MongODM.Core/Migration/DocumentMigration.cs +++ b/src/MongODM.Core/Migration/DocumentMigration.cs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Driver; using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Repositories; -using MongoDB.Driver; using System; using System.Threading; using System.Threading.Tasks; diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index bb3d64e7..18beb95a 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -23,6 +23,8 @@ + + all @@ -32,8 +34,6 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - - diff --git a/src/MongODM.Core/Repositories/CollectionRepository.cs b/src/MongODM.Core/Repositories/CollectionRepository.cs index 8f767024..e1dc8281 100644 --- a/src/MongODM.Core/Repositories/CollectionRepository.cs +++ b/src/MongODM.Core/Repositories/CollectionRepository.cs @@ -12,14 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson; +using Etherna.MongoDB.Driver; +using Etherna.MongoDB.Driver.Linq; using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Exceptions; using Etherna.MongODM.Core.Extensions; using Etherna.MongODM.Core.ProxyModels; using Etherna.MongODM.Core.Serialization.Mapping; -using MongoDB.Bson; -using MongoDB.Driver; -using MongoDB.Driver.Linq; using System; using System.Collections.Generic; using System.Linq; diff --git a/src/MongODM.Core/Repositories/CollectionRepositoryOptions.cs b/src/MongODM.Core/Repositories/CollectionRepositoryOptions.cs index e10baee9..9683f4bb 100644 --- a/src/MongODM.Core/Repositories/CollectionRepositoryOptions.cs +++ b/src/MongODM.Core/Repositories/CollectionRepositoryOptions.cs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Driver; +using Etherna.MongoDB.Driver; using System; using System.Collections.Generic; diff --git a/src/MongODM.Core/Repositories/GridFSRepository.cs b/src/MongODM.Core/Repositories/GridFSRepository.cs index 1f1bed4c..2fc1054f 100644 --- a/src/MongODM.Core/Repositories/GridFSRepository.cs +++ b/src/MongODM.Core/Repositories/GridFSRepository.cs @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson; +using Etherna.MongoDB.Driver; +using Etherna.MongoDB.Driver.GridFS; using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Exceptions; using Etherna.MongODM.Core.Serialization.Mapping; -using MongoDB.Bson; -using MongoDB.Driver; -using MongoDB.Driver.GridFS; using System; using System.Collections.Generic; using System.IO; diff --git a/src/MongODM.Core/Repositories/GridFSRepositoryOptions.cs b/src/MongODM.Core/Repositories/GridFSRepositoryOptions.cs index 59d75c56..8f443ff7 100644 --- a/src/MongODM.Core/Repositories/GridFSRepositoryOptions.cs +++ b/src/MongODM.Core/Repositories/GridFSRepositoryOptions.cs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson; +using Etherna.MongoDB.Bson; using System; namespace Etherna.MongODM.Core.Repositories diff --git a/src/MongODM.Core/Repositories/ICollectionRepository.cs b/src/MongODM.Core/Repositories/ICollectionRepository.cs index 6ec73972..7ee08b12 100644 --- a/src/MongODM.Core/Repositories/ICollectionRepository.cs +++ b/src/MongODM.Core/Repositories/ICollectionRepository.cs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Driver; +using Etherna.MongoDB.Driver.Linq; using Etherna.MongODM.Core.Domain.Models; -using MongoDB.Driver; -using MongoDB.Driver.Linq; using System; using System.Linq.Expressions; using System.Threading; diff --git a/src/MongODM.Core/Repositories/IGridFSRepository.cs b/src/MongODM.Core/Repositories/IGridFSRepository.cs index 5ed597ef..454e1f10 100644 --- a/src/MongODM.Core/Repositories/IGridFSRepository.cs +++ b/src/MongODM.Core/Repositories/IGridFSRepository.cs @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Driver.GridFS; using Etherna.MongODM.Core.Domain.Models; -using MongoDB.Driver.GridFS; using System.IO; using System.Threading; using System.Threading.Tasks; diff --git a/src/MongODM.Core/Serialization/ExtendedBsonDocumentWriter.cs b/src/MongODM.Core/Serialization/ExtendedBsonDocumentWriter.cs index a3131582..ad4191db 100644 --- a/src/MongODM.Core/Serialization/ExtendedBsonDocumentWriter.cs +++ b/src/MongODM.Core/Serialization/ExtendedBsonDocumentWriter.cs @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson; -using MongoDB.Bson.IO; +using Etherna.MongoDB.Bson; +using Etherna.MongoDB.Bson.IO; namespace Etherna.MongODM.Core.Serialization { diff --git a/src/MongODM.Core/Serialization/Mapping/IModelMap.cs b/src/MongODM.Core/Serialization/Mapping/IModelMap.cs index 9008b398..ff800a9e 100644 --- a/src/MongODM.Core/Serialization/Mapping/IModelMap.cs +++ b/src/MongODM.Core/Serialization/Mapping/IModelMap.cs @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson.Serialization; using Etherna.MongODM.Core.Utility; -using MongoDB.Bson.Serialization; using System; namespace Etherna.MongODM.Core.Serialization.Mapping diff --git a/src/MongODM.Core/Serialization/Mapping/ISchemaRegister.cs b/src/MongODM.Core/Serialization/Mapping/ISchemaRegister.cs index 4f36761a..8386184f 100644 --- a/src/MongODM.Core/Serialization/Mapping/ISchemaRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/ISchemaRegister.cs @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson; +using Etherna.MongoDB.Bson.Serialization; using Etherna.MongODM.Core.Serialization.Mapping.Schemas; using Etherna.MongODM.Core.Utility; -using MongoDB.Bson; -using MongoDB.Bson.Serialization; using System; using System.Collections.Generic; using System.Reflection; diff --git a/src/MongODM.Core/Serialization/Mapping/MemberDependency.cs b/src/MongODM.Core/Serialization/Mapping/MemberDependency.cs index 9584739e..f18bdbc2 100644 --- a/src/MongODM.Core/Serialization/Mapping/MemberDependency.cs +++ b/src/MongODM.Core/Serialization/Mapping/MemberDependency.cs @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson.Serialization; using Etherna.MongODM.Core.Extensions; -using MongoDB.Bson.Serialization; using System; using System.Collections.Generic; using System.Linq; diff --git a/src/MongODM.Core/Serialization/Mapping/ModelMap.cs b/src/MongODM.Core/Serialization/Mapping/ModelMap.cs index a96ff0e3..abeb4d31 100644 --- a/src/MongODM.Core/Serialization/Mapping/ModelMap.cs +++ b/src/MongODM.Core/Serialization/Mapping/ModelMap.cs @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson.Serialization; using Etherna.MongODM.Core.Extensions; using Etherna.MongODM.Core.Serialization.Serializers; using Etherna.MongODM.Core.Utility; -using MongoDB.Bson.Serialization; using System; using System.Linq; using System.Reflection; diff --git a/src/MongODM.Core/Serialization/Mapping/OwnedBsonMemberMap.cs b/src/MongODM.Core/Serialization/Mapping/OwnedBsonMemberMap.cs index b940278e..daa68f1a 100644 --- a/src/MongODM.Core/Serialization/Mapping/OwnedBsonMemberMap.cs +++ b/src/MongODM.Core/Serialization/Mapping/OwnedBsonMemberMap.cs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization; namespace Etherna.MongODM.Core.Serialization.Mapping { diff --git a/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs b/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs index b1aeb657..afed551f 100644 --- a/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs @@ -12,12 +12,12 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson; +using Etherna.MongoDB.Bson.Serialization; using Etherna.MongODM.Core.Extensions; using Etherna.MongODM.Core.Serialization.Mapping.Schemas; using Etherna.MongODM.Core.Serialization.Serializers; using Etherna.MongODM.Core.Utility; -using MongoDB.Bson; -using MongoDB.Bson.Serialization; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/CustomSerializerSchema.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/CustomSerializerSchema.cs index 192b0537..bc3a5b2a 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/CustomSerializerSchema.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/CustomSerializerSchema.cs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization; using System; namespace Etherna.MongODM.Core.Serialization.Mapping.Schemas diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchema.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchema.cs index fa31c451..f7211484 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchema.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchema.cs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization; using System.Collections.Generic; namespace Etherna.MongODM.Core.Serialization.Mapping.Schemas diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchemaBuilder.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchemaBuilder.cs index e26ad5d0..11edbced 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchemaBuilder.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchemaBuilder.cs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization; using System; namespace Etherna.MongODM.Core.Serialization.Mapping.Schemas diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/IReferenceModelMapsSchemaBuilder.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/IReferenceModelMapsSchemaBuilder.cs index 586def86..ec234056 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/IReferenceModelMapsSchemaBuilder.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/IReferenceModelMapsSchemaBuilder.cs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization; using System; namespace Etherna.MongODM.Core.Serialization.Mapping.Schemas diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/ISchema.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/ISchema.cs index c65768fe..fb2801e7 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/ISchema.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/ISchema.cs @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson.Serialization; using Etherna.MongODM.Core.Utility; -using MongoDB.Bson.Serialization; using System; namespace Etherna.MongODM.Core.Serialization.Mapping.Schemas diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchema.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchema.cs index 68a07b4c..2dcb7591 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchema.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchema.cs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization; using System; using System.Diagnostics.CodeAnalysis; diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchemaBase.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchemaBase.cs index a208a8cf..d80381c6 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchemaBase.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchemaBase.cs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization; using System; using System.Collections.Generic; using System.Linq; diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/ReferenceModelMapsSchema.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/ReferenceModelMapsSchema.cs index 3f925241..7dc1ce50 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/ReferenceModelMapsSchema.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/ReferenceModelMapsSchema.cs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization; using System; using System.Diagnostics.CodeAnalysis; diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/SchemaBase.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/SchemaBase.cs index 48fd499f..1dad67ca 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/SchemaBase.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/SchemaBase.cs @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson.Serialization; using Etherna.MongODM.Core.Utility; -using MongoDB.Bson.Serialization; using System; namespace Etherna.MongODM.Core.Serialization.Mapping.Schemas diff --git a/src/MongODM.Core/Serialization/SemanticVersion.cs b/src/MongODM.Core/Serialization/SemanticVersion.cs index 488fea21..3a91d6f1 100644 --- a/src/MongODM.Core/Serialization/SemanticVersion.cs +++ b/src/MongODM.Core/Serialization/SemanticVersion.cs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson; +using Etherna.MongoDB.Bson; using System; using System.Globalization; using System.Text; diff --git a/src/MongODM.Core/Serialization/Serializers/DictionarySerializer.cs b/src/MongODM.Core/Serialization/Serializers/DictionarySerializer.cs index 0e1eaa4e..93dd8ca2 100644 --- a/src/MongODM.Core/Serialization/Serializers/DictionarySerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/DictionarySerializer.cs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Options; -using MongoDB.Bson.Serialization.Serializers; +using Etherna.MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization.Options; +using Etherna.MongoDB.Bson.Serialization.Serializers; using System; using System.Collections.Generic; diff --git a/src/MongODM.Core/Serialization/Serializers/EnumerableSerializer.cs b/src/MongODM.Core/Serialization/Serializers/EnumerableSerializer.cs index 10dff32d..27803b36 100644 --- a/src/MongODM.Core/Serialization/Serializers/EnumerableSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/EnumerableSerializer.cs @@ -12,8 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Serializers; +using Etherna.MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization.Serializers; using System; using System.Collections.Generic; diff --git a/src/MongODM.Core/Serialization/Serializers/ExtraElementsSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ExtraElementsSerializer.cs index 9e4d969a..db1f6cd6 100644 --- a/src/MongODM.Core/Serialization/Serializers/ExtraElementsSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ExtraElementsSerializer.cs @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson; -using MongoDB.Bson.IO; -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Serializers; +using Etherna.MongoDB.Bson; +using Etherna.MongoDB.Bson.IO; +using Etherna.MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization.Serializers; using System; using System.Collections.Generic; diff --git a/src/MongODM.Core/Serialization/Serializers/GeoPointSerializer.cs b/src/MongODM.Core/Serialization/Serializers/GeoPointSerializer.cs index abdbe92b..edeaa571 100644 --- a/src/MongODM.Core/Serialization/Serializers/GeoPointSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/GeoPointSerializer.cs @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization.Serializers; +using Etherna.MongoDB.Driver.GeoJsonObjectModel; +using Etherna.MongoDB.Driver.GeoJsonObjectModel.Serializers; using Etherna.MongODM.Core.ProxyModels; -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Serializers; -using MongoDB.Driver.GeoJsonObjectModel; -using MongoDB.Driver.GeoJsonObjectModel.Serializers; using System; using System.Linq.Expressions; using System.Reflection; diff --git a/src/MongODM.Core/Serialization/Serializers/HexToBinaryDataSerializer.cs b/src/MongODM.Core/Serialization/Serializers/HexToBinaryDataSerializer.cs index c6fc38d8..9feed504 100644 --- a/src/MongODM.Core/Serialization/Serializers/HexToBinaryDataSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/HexToBinaryDataSerializer.cs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson; -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Serializers; +using Etherna.MongoDB.Bson; +using Etherna.MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization.Serializers; using System; namespace Etherna.MongODM.Core.Serialization.Serializers diff --git a/src/MongODM.Core/Serialization/Serializers/IModelMapsContainerSerializer.cs b/src/MongODM.Core/Serialization/Serializers/IModelMapsContainerSerializer.cs index f4b14035..b66b9251 100644 --- a/src/MongODM.Core/Serialization/Serializers/IModelMapsContainerSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/IModelMapsContainerSerializer.cs @@ -12,7 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization; using System.Collections.Generic; namespace Etherna.MongODM.Core.Serialization.Serializers diff --git a/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs index 7ada6e5b..51cc748f 100644 --- a/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs @@ -12,17 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson; +using Etherna.MongoDB.Bson.IO; +using Etherna.MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization.Conventions; +using Etherna.MongoDB.Bson.Serialization.Serializers; using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Options; using Etherna.MongODM.Core.ProxyModels; using Etherna.MongODM.Core.Serialization.Mapping; using Etherna.MongODM.Core.Serialization.Modifiers; using Etherna.MongODM.Core.Utility; -using MongoDB.Bson; -using MongoDB.Bson.IO; -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Conventions; -using MongoDB.Bson.Serialization.Serializers; using System; using System.Collections.Generic; using System.Linq; diff --git a/src/MongODM.Core/Serialization/Serializers/ReadOnlyDictionarySerializer.cs b/src/MongODM.Core/Serialization/Serializers/ReadOnlyDictionarySerializer.cs index 118346b5..98ffcc89 100644 --- a/src/MongODM.Core/Serialization/Serializers/ReadOnlyDictionarySerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ReadOnlyDictionarySerializer.cs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Options; -using MongoDB.Bson.Serialization.Serializers; +using Etherna.MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization.Options; +using Etherna.MongoDB.Bson.Serialization.Serializers; using System; using System.Collections.Generic; diff --git a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs index f1d60732..522f38cd 100644 --- a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs @@ -12,13 +12,13 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson; +using Etherna.MongoDB.Bson.IO; +using Etherna.MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization.Conventions; +using Etherna.MongoDB.Bson.Serialization.Serializers; using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.ProxyModels; -using MongoDB.Bson; -using MongoDB.Bson.IO; -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Conventions; -using MongoDB.Bson.Serialization.Serializers; using System; using System.Collections.Generic; using System.Linq; diff --git a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerAdapter.cs b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerAdapter.cs index 51124f68..351ce397 100644 --- a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerAdapter.cs +++ b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerAdapter.cs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson.Serialization; +using Etherna.MongoDB.Bson.Serialization.Serializers; using Etherna.MongODM.Core.Domain.Models; -using MongoDB.Bson.Serialization; -using MongoDB.Bson.Serialization.Serializers; using System; using System.Collections.Generic; diff --git a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerConfiguration.cs b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerConfiguration.cs index 7604f388..7ea239c3 100644 --- a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerConfiguration.cs +++ b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerConfiguration.cs @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson; +using Etherna.MongoDB.Bson.Serialization; using Etherna.MongODM.Core.Serialization.Mapping; using Etherna.MongODM.Core.Serialization.Mapping.Schemas; using Etherna.MongODM.Core.Utility; -using MongoDB.Bson; -using MongoDB.Bson.Serialization; using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; diff --git a/src/MongODM.Core/Tasks/UpdateDocDependenciesTask.cs b/src/MongODM.Core/Tasks/UpdateDocDependenciesTask.cs index da017e79..09bce9fe 100644 --- a/src/MongODM.Core/Tasks/UpdateDocDependenciesTask.cs +++ b/src/MongODM.Core/Tasks/UpdateDocDependenciesTask.cs @@ -12,10 +12,10 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Driver; using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Repositories; using Etherna.MongODM.Core.Serialization.Modifiers; -using MongoDB.Driver; using System; using System.Collections.Generic; using System.Threading.Tasks; diff --git a/src/MongODM.Core/Utility/DbMaintainer.cs b/src/MongODM.Core/Utility/DbMaintainer.cs index b5bc2c45..5ee47106 100644 --- a/src/MongODM.Core/Utility/DbMaintainer.cs +++ b/src/MongODM.Core/Utility/DbMaintainer.cs @@ -12,9 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Driver; using Etherna.MongODM.Core.ProxyModels; using Etherna.MongODM.Core.Tasks; -using MongoDB.Driver; using System; using System.Linq; diff --git a/src/MongODM.Core/Utility/DbMigrationManager.cs b/src/MongODM.Core/Utility/DbMigrationManager.cs index 20512c88..21ae69f0 100644 --- a/src/MongODM.Core/Utility/DbMigrationManager.cs +++ b/src/MongODM.Core/Utility/DbMigrationManager.cs @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Driver; +using Etherna.MongoDB.Driver.Linq; using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Extensions; using Etherna.MongODM.Core.Tasks; -using MongoDB.Driver; -using MongoDB.Driver.Linq; using System; using System.Collections.Generic; using System.Threading.Tasks; diff --git a/test/MongODM.Core.Tests/ModelMapSerializerTest.cs b/test/MongODM.Core.Tests/ModelMapSerializerTest.cs index d1bd586a..86e42b9a 100644 --- a/test/MongODM.Core.Tests/ModelMapSerializerTest.cs +++ b/test/MongODM.Core.Tests/ModelMapSerializerTest.cs @@ -12,6 +12,9 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Bson; +using Etherna.MongoDB.Bson.IO; +using Etherna.MongoDB.Bson.Serialization; using Etherna.MongODM.Core.Comparers; using Etherna.MongODM.Core.Models; using Etherna.MongODM.Core.Options; @@ -20,9 +23,6 @@ using Etherna.MongODM.Core.Serialization.Modifiers; using Etherna.MongODM.Core.Serialization.Serializers; using Etherna.MongODM.Core.Utility; -using MongoDB.Bson; -using MongoDB.Bson.IO; -using MongoDB.Bson.Serialization; using Moq; using System; using System.Collections.Generic; From f0c809892f3c588fca13f9f053b96b2340025827 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Wed, 8 Dec 2021 01:48:45 +0100 Subject: [PATCH 35/78] Passing SerializerRegister to database options --- src/MongODM.Core/DbContext.cs | 6 +++++- src/MongODM.Core/MongODM.Core.csproj | 4 ++-- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index 20315d5c..0cb44c79 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -74,11 +74,15 @@ public async Task InitializeAsync( // Initialize MongoDB driver. Client = new MongoClient(options.ConnectionString); - Database = Client.GetDatabase(options.DbName); + Database = Client.GetDatabase(options.DbName, new MongoDatabaseSettings + { + SerializerRegistry = _serializerRegister + }); // Initialize internal dependencies. DbMaintainer.Initialize(this); DbMigrationManager.Initialize(this); + DiscriminatorRegister.Initialize(this); RepositoryRegister.Initialize(this); SchemaRegister.Initialize(this); InitializeSerializerRegister(); diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index 18beb95a..498dbe70 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -23,8 +23,8 @@ - - + + all From d15ce382195873265d2d07e7fc417b2450b98667 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Wed, 8 Dec 2021 02:06:39 +0100 Subject: [PATCH 36/78] Fixed tests --- test/MongODM.Core.Tests/ModelMapSerializerTest.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/MongODM.Core.Tests/ModelMapSerializerTest.cs b/test/MongODM.Core.Tests/ModelMapSerializerTest.cs index ffc680d9..92e491bd 100644 --- a/test/MongODM.Core.Tests/ModelMapSerializerTest.cs +++ b/test/MongODM.Core.Tests/ModelMapSerializerTest.cs @@ -16,6 +16,7 @@ using Etherna.MongoDB.Bson.IO; using Etherna.MongoDB.Bson.Serialization; using Etherna.MongODM.Core.Comparers; +using Etherna.MongODM.Core.Conventions; using Etherna.MongODM.Core.Models; using Etherna.MongODM.Core.Options; using Etherna.MongODM.Core.Serialization.Mapping; @@ -79,6 +80,7 @@ public SerializationTestElement( // Fields. private readonly Mock dbCacheMock = new(); private readonly Mock dbContextMock = new(); + private readonly Mock discriminatorRegisterMock = new(); private readonly DocumentSemVerOptions documentSemVerOptions = new(); private readonly Mock modelMapsSchemaMock = new(); private readonly ModelMapVersionOptions modelMapVersionOptions = new(); @@ -88,11 +90,16 @@ public SerializationTestElement( // Constructor. public ModelMapSerializerTest() { + discriminatorRegisterMock.Setup(r => r.LookupDiscriminatorConvention(It.IsAny())) + .Returns(() => new HierarchicalProxyTolerantDiscriminatorConvention(dbContextMock.Object, "_t")); + dbCacheMock.Setup(c => c.LoadedModels.ContainsKey(It.IsAny())) .Returns(() => false); dbContextMock.Setup(c => c.DbCache) .Returns(() => dbCacheMock.Object); + dbContextMock.Setup(c => c.DiscriminatorRegister) + .Returns(() => discriminatorRegisterMock.Object); dbContextMock.Setup(c => c.Options.DocumentSemVer) .Returns(() => documentSemVerOptions); dbContextMock.Setup(c => c.Options.ModelMapVersion) From 6c32d4e7b83c3dfb5a2d87b86cdc6aa92c60e87b Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Mon, 13 Dec 2021 00:53:03 +0100 Subject: [PATCH 37/78] Fixed registry naming --- .../Models/ModelMaps/CatMap.cs | 2 +- .../Models/ModelMaps/ModelBaseMap.cs | 4 +- src/MongODM.AspNetCore/DbDependencies.cs | 18 +++---- .../ServiceCollectionExtensions.cs | 6 +-- ...calProxyTolerantDiscriminatorConvention.cs | 6 +-- src/MongODM.Core/DbContext.cs | 50 +++++++++---------- .../ModelMaps/DbMigrationOperationMap.cs | 8 +-- .../Domain/ModelMaps/ModelBaseMap.cs | 6 +-- .../Domain/ModelMaps/OperationBaseMap.cs | 2 +- .../Domain/ModelMaps/SeedOperationMap.cs | 2 +- src/MongODM.Core/IDbContext.cs | 16 +++--- src/MongODM.Core/IDbDependencies.cs | 6 +-- .../ProxyModels/ReferenceableInterceptor.cs | 4 +- src/MongODM.Core/ReflectionHelper.cs | 22 ++++---- .../Repositories/CollectionRepository.cs | 4 +- .../Repositories/GridFSRepository.cs | 2 +- src/MongODM.Core/Repositories/IRepository.cs | 2 +- ...toryRegister.cs => IRepositoryRegistry.cs} | 2 +- .../Repositories/RepositoryBase.cs | 6 +-- ...itoryRegister.cs => RepositoryRegistry.cs} | 6 +-- ...orRegister.cs => DiscriminatorRegistry.cs} | 2 +- ...rRegister.cs => IDiscriminatorRegistry.cs} | 2 +- ...{ISchemaRegister.cs => ISchemaRegistry.cs} | 4 +- .../{SchemaRegister.cs => SchemaRegistry.cs} | 8 +-- .../Serializers/ExtraElementsSerializer.cs | 4 +- .../Serializers/ModelMapSerializer.cs | 12 ++--- .../Serializers/ReferenceSerializer.cs | 2 +- .../Tasks/MigrateDbContextTask.cs | 4 +- .../Tasks/UpdateDocDependenciesTask.cs | 4 +- src/MongODM.Core/Utility/DbMaintainer.cs | 4 +- .../ModelMapSerializerTest.cs | 18 +++---- .../ReferenceableInterceptorTest.cs | 2 +- 32 files changed, 120 insertions(+), 120 deletions(-) rename src/MongODM.Core/Repositories/{IRepositoryRegister.cs => IRepositoryRegistry.cs} (95%) rename src/MongODM.Core/Repositories/{RepositoryRegister.cs => RepositoryRegistry.cs} (97%) rename src/MongODM.Core/Serialization/Mapping/{DiscriminatorRegister.cs => DiscriminatorRegistry.cs} (99%) rename src/MongODM.Core/Serialization/Mapping/{IDiscriminatorRegister.cs => IDiscriminatorRegistry.cs} (94%) rename src/MongODM.Core/Serialization/Mapping/{ISchemaRegister.cs => ISchemaRegistry.cs} (97%) rename src/MongODM.Core/Serialization/Mapping/{SchemaRegister.cs => SchemaRegistry.cs} (98%) diff --git a/samples/AspNetCoreSample/Models/ModelMaps/CatMap.cs b/samples/AspNetCoreSample/Models/ModelMaps/CatMap.cs index 9f38fcbd..9af473be 100644 --- a/samples/AspNetCoreSample/Models/ModelMaps/CatMap.cs +++ b/samples/AspNetCoreSample/Models/ModelMaps/CatMap.cs @@ -21,7 +21,7 @@ class CatMap : IModelMapsCollector { public void Register(IDbContext dbContext) { - dbContext.SchemaRegister.AddModelMapsSchema("cd37bafa-a36d-4b1f-815a-deb50c49d030"); + dbContext.SchemaRegistry.AddModelMapsSchema("cd37bafa-a36d-4b1f-815a-deb50c49d030"); } } } diff --git a/samples/AspNetCoreSample/Models/ModelMaps/ModelBaseMap.cs b/samples/AspNetCoreSample/Models/ModelMaps/ModelBaseMap.cs index 3d6bcbc7..231f738e 100644 --- a/samples/AspNetCoreSample/Models/ModelMaps/ModelBaseMap.cs +++ b/samples/AspNetCoreSample/Models/ModelMaps/ModelBaseMap.cs @@ -24,9 +24,9 @@ class ModelBaseMap : IModelMapsCollector { public void Register(IDbContext dbContext) { - dbContext.SchemaRegister.AddModelMapsSchema("1252861f-82d9-4c72-975e-3571d5e1b6e6"); + dbContext.SchemaRegistry.AddModelMapsSchema("1252861f-82d9-4c72-975e-3571d5e1b6e6"); - dbContext.SchemaRegister.AddModelMapsSchema>("81dd8b35-a0af-44d9-80b4-ab7ae9844eb5", modelMap => + dbContext.SchemaRegistry.AddModelMapsSchema>("81dd8b35-a0af-44d9-80b4-ab7ae9844eb5", modelMap => { modelMap.AutoMap(); diff --git a/src/MongODM.AspNetCore/DbDependencies.cs b/src/MongODM.AspNetCore/DbDependencies.cs index c0284865..bc1107ed 100644 --- a/src/MongODM.AspNetCore/DbDependencies.cs +++ b/src/MongODM.AspNetCore/DbDependencies.cs @@ -32,11 +32,11 @@ public DbDependencies( IDbCache dbCache, IDbMaintainer dbMaintainer, IDbMigrationManager dbContextMigrationManager, - IDiscriminatorRegister discriminatorRegister, + IDiscriminatorRegistry discriminatorRegistry, IOptions mongODMOptions, IProxyGenerator proxyGenerator, - IRepositoryRegister repositoryRegister, - ISchemaRegister schemaRegister, + IRepositoryRegistry repositoryRegistry, + ISchemaRegistry schemaRegistry, ISerializerModifierAccessor serializerModifierAccessor) { if (mongODMOptions is null) @@ -45,11 +45,11 @@ public DbDependencies( DbCache = dbCache; DbMaintainer = dbMaintainer; DbMigrationManager = dbContextMigrationManager; - DiscriminatorRegister = discriminatorRegister; + DiscriminatorRegistry = discriminatorRegistry; MongODMOptions = mongODMOptions.Value; - SchemaRegister = schemaRegister; + SchemaRegistry = schemaRegistry; ProxyGenerator = proxyGenerator; - RepositoryRegister = repositoryRegister; + RepositoryRegistry = repositoryRegistry; SerializerModifierAccessor = serializerModifierAccessor; } @@ -57,11 +57,11 @@ public DbDependencies( public IDbCache DbCache { get; } public IDbMaintainer DbMaintainer { get; } public IDbMigrationManager DbMigrationManager { get; } - public IDiscriminatorRegister DiscriminatorRegister { get; } + public IDiscriminatorRegistry DiscriminatorRegistry { get; } public MongODMOptions MongODMOptions { get; } public IProxyGenerator ProxyGenerator { get; } - public IRepositoryRegister RepositoryRegister { get; } - public ISchemaRegister SchemaRegister { get; } + public IRepositoryRegistry RepositoryRegistry { get; } + public ISchemaRegistry SchemaRegistry { get; } public ISerializerModifierAccessor SerializerModifierAccessor { get; } } } diff --git a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs index 9792fbad..dc72bc9c 100644 --- a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs +++ b/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs @@ -83,9 +83,9 @@ public static IMongODMConfiguration AddMongODM( services.TryAddTransient(); services.TryAddTransient(); services.TryAddTransient(); - services.TryAddTransient(); - services.TryAddTransient(); - services.TryAddTransient(); + services.TryAddTransient(); + services.TryAddTransient(); + services.TryAddTransient(); services.TryAddSingleton(); //tasks diff --git a/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs b/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs index 304cba80..629fac12 100644 --- a/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs +++ b/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs @@ -53,7 +53,7 @@ public Type GetActualType(IBsonReader bsonReader, Type nominalType) if (bsonType == BsonType.Document) { //we can skip looking for a discriminator if nominalType has no discriminated sub types - if (dbContext.DiscriminatorRegister.IsTypeDiscriminated(nominalType)) + if (dbContext.DiscriminatorRegistry.IsTypeDiscriminated(nominalType)) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); @@ -66,7 +66,7 @@ public Type GetActualType(IBsonReader bsonReader, Type nominalType) { discriminator = discriminator.AsBsonArray.Last(); //last item is leaf class discriminator } - actualType = dbContext.DiscriminatorRegister.LookupActualType(nominalType, discriminator); + actualType = dbContext.DiscriminatorRegistry.LookupActualType(nominalType, discriminator); } bsonReader.ReturnToBookmark(bookmark); return actualType; @@ -88,7 +88,7 @@ public Type GetActualType(IBsonReader bsonReader, Type nominalType) actualType = dbContext.ProxyGenerator.PurgeProxyType(actualType); // Find active class map for model type. - var classMap = dbContext.SchemaRegister.GetActiveClassMap(actualType); + var classMap = dbContext.SchemaRegistry.GetActiveClassMap(actualType); // Get discriminator from class map. if (actualType != nominalType || classMap.DiscriminatorIsRequired || classMap.HasRootClass) diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index 0cb44c79..a5f39f01 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -37,7 +37,7 @@ namespace Etherna.MongODM.Core public abstract class DbContext : IDbContext, IDbContextBuilder { // Fields. - private BsonSerializerRegistry _serializerRegister = default!; + private BsonSerializerRegistry _serializerRegistry = default!; private bool isInitialized; // Constructor and initializer. @@ -58,7 +58,7 @@ public async Task InitializeAsync( DbMaintainer = dependencies.DbMaintainer; DbMigrationManager = dependencies.DbMigrationManager; DbOperations = new CollectionRepository(options.DbOperationsCollectionName); - DiscriminatorRegister = dependencies.DiscriminatorRegister; + DiscriminatorRegistry = dependencies.DiscriminatorRegistry; LibraryVersion = typeof(DbContext) .GetTypeInfo() .Assembly @@ -67,28 +67,28 @@ public async Task InitializeAsync( ?.Split('+')[0] ?? "1.0.0"; Options = options; ProxyGenerator = dependencies.ProxyGenerator; - RepositoryRegister = dependencies.RepositoryRegister; - SchemaRegister = dependencies.SchemaRegister; + RepositoryRegistry = dependencies.RepositoryRegistry; + SchemaRegistry = dependencies.SchemaRegistry; SerializerModifierAccessor = dependencies.SerializerModifierAccessor; - _serializerRegister = (BsonSerializerRegistry)dependencies.BsonSerializerRegistry; + _serializerRegistry = (BsonSerializerRegistry)dependencies.BsonSerializerRegistry; // Initialize MongoDB driver. Client = new MongoClient(options.ConnectionString); Database = Client.GetDatabase(options.DbName, new MongoDatabaseSettings { - SerializerRegistry = _serializerRegister + SerializerRegistry = _serializerRegistry }); // Initialize internal dependencies. DbMaintainer.Initialize(this); DbMigrationManager.Initialize(this); - DiscriminatorRegister.Initialize(this); - RepositoryRegister.Initialize(this); - SchemaRegister.Initialize(this); - InitializeSerializerRegister(); + DiscriminatorRegistry.Initialize(this); + RepositoryRegistry.Initialize(this); + SchemaRegistry.Initialize(this); + InitializeSerializerRegistry(); // Initialize repositories. - foreach (var repository in RepositoryRegister.ModelRepositoryMap.Values) + foreach (var repository in RepositoryRegistry.ModelRepositoryMap.Values) repository.Initialize(this); // Register model maps. @@ -102,8 +102,8 @@ public async Task InitializeAsync( foreach (var maps in ModelMapsCollectors) maps.Register(this); - // Build and freeze schemas register. - SchemaRegister.Freeze(); + // Build and freeze schema registry. + SchemaRegistry.Freeze(); // Initialize data. if (!Options.DisableAutomaticSeed) @@ -124,15 +124,15 @@ public async Task InitializeAsync( public IDbMaintainer DbMaintainer { get; private set; } = default!; public IDbMigrationManager DbMigrationManager { get; private set; } = default!; public ICollectionRepository DbOperations { get; private set; } = default!; - public IDiscriminatorRegister DiscriminatorRegister { get; private set; } = default!; + public IDiscriminatorRegistry DiscriminatorRegistry { get; private set; } = default!; public virtual IEnumerable DocumentMigrationList { get; } = Array.Empty(); public string Identifier => Options?.Identifier ?? GetType().Name; public SemanticVersion LibraryVersion { get; private set; } = default!; public IDbContextOptions Options { get; private set; } = default!; public IProxyGenerator ProxyGenerator { get; private set; } = default!; - public IRepositoryRegister RepositoryRegister { get; private set; } = default!; - public IBsonSerializerRegistry SerializerRegister => _serializerRegister; - public ISchemaRegister SchemaRegister { get; private set; } = default!; + public IRepositoryRegistry RepositoryRegistry { get; private set; } = default!; + public IBsonSerializerRegistry SerializerRegistry => _serializerRegistry; + public ISchemaRegistry SchemaRegistry { get; private set; } = default!; public ISerializerModifierAccessor SerializerModifierAccessor { get; private set; } = default!; // Protected properties. @@ -177,9 +177,9 @@ public virtual async Task SaveChangesAsync(CancellationToken cancellationToken = var modelType = ProxyGenerator.PurgeProxyType(model.GetType()); while (modelType != typeof(object)) //try to find right collection. Can't replace model if it is stored on gridfs { - if (RepositoryRegister.ModelCollectionRepositoryMap.ContainsKey(modelType)) + if (RepositoryRegistry.ModelCollectionRepositoryMap.ContainsKey(modelType)) { - var repository = RepositoryRegister.ModelCollectionRepositoryMap[modelType]; + var repository = RepositoryRegistry.ModelCollectionRepositoryMap[modelType]; await repository.ReplaceAsync(model, cancellationToken: cancellationToken).ConfigureAwait(false); break; } @@ -217,14 +217,14 @@ protected virtual Task SeedAsync() => Task.CompletedTask; // Helpers. - private void InitializeSerializerRegister() + private void InitializeSerializerRegistry() { //order matters. It's in reverse order of how they'll get consumed - _serializerRegister.RegisterSerializationProvider(new DiscriminatedInterfaceSerializationProvider()); - _serializerRegister.RegisterSerializationProvider(new CollectionsSerializationProvider()); - _serializerRegister.RegisterSerializationProvider(new PrimitiveSerializationProvider()); - _serializerRegister.RegisterSerializationProvider(new AttributedSerializationProvider()); - _serializerRegister.RegisterSerializationProvider(new BsonObjectModelSerializationProvider()); + _serializerRegistry.RegisterSerializationProvider(new DiscriminatedInterfaceSerializationProvider()); + _serializerRegistry.RegisterSerializationProvider(new CollectionsSerializationProvider()); + _serializerRegistry.RegisterSerializationProvider(new PrimitiveSerializationProvider()); + _serializerRegistry.RegisterSerializationProvider(new AttributedSerializationProvider()); + _serializerRegistry.RegisterSerializationProvider(new BsonObjectModelSerializationProvider()); } } } \ No newline at end of file diff --git a/src/MongODM.Core/Domain/ModelMaps/DbMigrationOperationMap.cs b/src/MongODM.Core/Domain/ModelMaps/DbMigrationOperationMap.cs index db25fc76..1ab63a4e 100644 --- a/src/MongODM.Core/Domain/ModelMaps/DbMigrationOperationMap.cs +++ b/src/MongODM.Core/Domain/ModelMaps/DbMigrationOperationMap.cs @@ -22,13 +22,13 @@ class DbMigrationOperationMap : IModelMapsCollector { public void Register(IDbContext dbContext) { - dbContext.SchemaRegister.AddModelMapsSchema("afdb63c9-791b-41f8-8216-556e233df0de"); + dbContext.SchemaRegistry.AddModelMapsSchema("afdb63c9-791b-41f8-8216-556e233df0de"); - dbContext.SchemaRegister.AddModelMapsSchema("1696c0c9-d615-44d9-ab9b-4e3618164185"); + dbContext.SchemaRegistry.AddModelMapsSchema("1696c0c9-d615-44d9-ab9b-4e3618164185"); - dbContext.SchemaRegister.AddModelMapsSchema("d2b49514-464e-4b28-8b38-ad2d0cc69d3e"); + dbContext.SchemaRegistry.AddModelMapsSchema("d2b49514-464e-4b28-8b38-ad2d0cc69d3e"); - dbContext.SchemaRegister.AddModelMapsSchema("24d65670-a3c3-443c-977a-51112df04e2a"); + dbContext.SchemaRegistry.AddModelMapsSchema("24d65670-a3c3-443c-977a-51112df04e2a"); } } } diff --git a/src/MongODM.Core/Domain/ModelMaps/ModelBaseMap.cs b/src/MongODM.Core/Domain/ModelMaps/ModelBaseMap.cs index 64250e43..6601ffce 100644 --- a/src/MongODM.Core/Domain/ModelMaps/ModelBaseMap.cs +++ b/src/MongODM.Core/Domain/ModelMaps/ModelBaseMap.cs @@ -24,10 +24,10 @@ class ModelBaseMap : IModelMapsCollector { public void Register(IDbContext dbContext) { - // register class maps. - dbContext.SchemaRegister.AddModelMapsSchema("bff55d53-0517-4a93-8fda-7bd448181449"); + // Register class maps. + dbContext.SchemaRegistry.AddModelMapsSchema("bff55d53-0517-4a93-8fda-7bd448181449"); - dbContext.SchemaRegister.AddModelMapsSchema>("586b48f5-ba1f-45e3-a812-744f88c1c969", + dbContext.SchemaRegistry.AddModelMapsSchema>("586b48f5-ba1f-45e3-a812-744f88c1c969", modelMap => { modelMap.AutoMap(); diff --git a/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs b/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs index a75ad3d3..ff7d2fdb 100644 --- a/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs +++ b/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs @@ -23,7 +23,7 @@ class OperationBaseMap : IModelMapsCollector { public void Register(IDbContext dbContext) { - dbContext.SchemaRegister.AddModelMapsSchema("ee726d4f-6e6a-44b0-bf3e-45322534c36d", + dbContext.SchemaRegistry.AddModelMapsSchema("ee726d4f-6e6a-44b0-bf3e-45322534c36d", customSerializer: new ModelMapSerializer( dbContext, new DocumentSemVerOptions diff --git a/src/MongODM.Core/Domain/ModelMaps/SeedOperationMap.cs b/src/MongODM.Core/Domain/ModelMaps/SeedOperationMap.cs index f26e0a38..3852cbcf 100644 --- a/src/MongODM.Core/Domain/ModelMaps/SeedOperationMap.cs +++ b/src/MongODM.Core/Domain/ModelMaps/SeedOperationMap.cs @@ -21,7 +21,7 @@ class SeedOperationMap : IModelMapsCollector { public void Register(IDbContext dbContext) { - dbContext.SchemaRegister.AddModelMapsSchema("f9bfe56e-8045-4559-b91b-4745c2fd9766"); + dbContext.SchemaRegistry.AddModelMapsSchema("f9bfe56e-8045-4559-b91b-4745c2fd9766"); } } } diff --git a/src/MongODM.Core/IDbContext.cs b/src/MongODM.Core/IDbContext.cs index 28e85a81..7d33f520 100644 --- a/src/MongODM.Core/IDbContext.cs +++ b/src/MongODM.Core/IDbContext.cs @@ -66,9 +66,9 @@ public interface IDbContext ICollectionRepository DbOperations { get; } /// - /// Register for discriminator configuration. + /// Registry for discriminator configuration. /// - IDiscriminatorRegister DiscriminatorRegister { get; } + IDiscriminatorRegistry DiscriminatorRegistry { get; } /// /// List of registered migration tasks @@ -96,19 +96,19 @@ public interface IDbContext IProxyGenerator ProxyGenerator { get; } /// - /// Register of available repositories. + /// Registry of available repositories. /// - IRepositoryRegister RepositoryRegister { get; } + IRepositoryRegistry RepositoryRegistry { get; } /// - /// Local instance of a serializer register. + /// Local instance of a serializer registry. /// - IBsonSerializerRegistry SerializerRegister { get; } + IBsonSerializerRegistry SerializerRegistry { get; } /// - /// Register for model serialization and schema information. + /// Registry for model serialization and schema information. /// - ISchemaRegister SchemaRegister { get; } + ISchemaRegistry SchemaRegistry { get; } /// /// Serializer modifier accessor. diff --git a/src/MongODM.Core/IDbDependencies.cs b/src/MongODM.Core/IDbDependencies.cs index 88fcb900..c9d1cce6 100644 --- a/src/MongODM.Core/IDbDependencies.cs +++ b/src/MongODM.Core/IDbDependencies.cs @@ -27,10 +27,10 @@ public interface IDbDependencies IDbCache DbCache { get; } IDbMaintainer DbMaintainer { get; } IDbMigrationManager DbMigrationManager { get; } - IDiscriminatorRegister DiscriminatorRegister { get; } + IDiscriminatorRegistry DiscriminatorRegistry { get; } IProxyGenerator ProxyGenerator { get; } - IRepositoryRegister RepositoryRegister { get; } - ISchemaRegister SchemaRegister { get; } + IRepositoryRegistry RepositoryRegistry { get; } + ISchemaRegistry SchemaRegistry { get; } ISerializerModifierAccessor SerializerModifierAccessor { get; } } } \ No newline at end of file diff --git a/src/MongODM.Core/ProxyModels/ReferenceableInterceptor.cs b/src/MongODM.Core/ProxyModels/ReferenceableInterceptor.cs index 3728f5d3..49638564 100644 --- a/src/MongODM.Core/ProxyModels/ReferenceableInterceptor.cs +++ b/src/MongODM.Core/ProxyModels/ReferenceableInterceptor.cs @@ -42,14 +42,14 @@ public ReferenceableInterceptor( throw new ArgumentNullException(nameof(dbContext)); var repositoryModelType = typeof(TModel); - while (!dbContext.RepositoryRegister.ModelRepositoryMap.ContainsKey(repositoryModelType)) + while (!dbContext.RepositoryRegistry.ModelRepositoryMap.ContainsKey(repositoryModelType)) { if (repositoryModelType == typeof(object)) throw new InvalidOperationException($"Cant find valid repository for model type {typeof(TModel)}"); repositoryModelType = repositoryModelType.BaseType; } - repository = dbContext.RepositoryRegister.ModelRepositoryMap[repositoryModelType]; + repository = dbContext.RepositoryRegistry.ModelRepositoryMap[repositoryModelType]; } // Protected methods. diff --git a/src/MongODM.Core/ReflectionHelper.cs b/src/MongODM.Core/ReflectionHelper.cs index a20ad33e..393fdb4b 100644 --- a/src/MongODM.Core/ReflectionHelper.cs +++ b/src/MongODM.Core/ReflectionHelper.cs @@ -23,8 +23,8 @@ namespace Etherna.MongODM.Core { public static class ReflectionHelper { - private static readonly Dictionary> propertyRegister = new(); - private static readonly ReaderWriterLockSlim propertyRegisterLock = new(); + private static readonly Dictionary> propertyRegistry = new(); + private static readonly ReaderWriterLockSlim propertyRegistryLock = new(); public static MemberInfo FindProperty(LambdaExpression lambdaExpression) { @@ -176,23 +176,23 @@ public static IEnumerable GetWritableInstanceProperties(Type objec if (objectType is null) throw new ArgumentNullException(nameof(objectType)); - propertyRegisterLock.EnterReadLock(); + propertyRegistryLock.EnterReadLock(); try { - if (propertyRegister.ContainsKey(objectType)) + if (propertyRegistry.ContainsKey(objectType)) { - return propertyRegister[objectType]; + return propertyRegistry[objectType]; } } finally { - propertyRegisterLock.ExitReadLock(); + propertyRegistryLock.ExitReadLock(); } - propertyRegisterLock.EnterWriteLock(); + propertyRegistryLock.EnterWriteLock(); try { - if (!propertyRegister.ContainsKey(objectType)) + if (!propertyRegistry.ContainsKey(objectType)) { var typeStack = new List(); var stackType = objectType; @@ -202,15 +202,15 @@ public static IEnumerable GetWritableInstanceProperties(Type objec stackType = stackType.BaseType; } while (stackType != null); - propertyRegister.Add(objectType, typeStack + propertyRegistry.Add(objectType, typeStack .SelectMany(type => type.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance)) .Where(prop => prop.CanWrite)); } - return propertyRegister[objectType]; + return propertyRegistry[objectType]; } finally { - propertyRegisterLock.ExitWriteLock(); + propertyRegistryLock.ExitWriteLock(); } } diff --git a/src/MongODM.Core/Repositories/CollectionRepository.cs b/src/MongODM.Core/Repositories/CollectionRepository.cs index e1dc8281..8af97b36 100644 --- a/src/MongODM.Core/Repositories/CollectionRepository.cs +++ b/src/MongODM.Core/Repositories/CollectionRepository.cs @@ -53,7 +53,7 @@ public CollectionRepository(CollectionRepositoryOptions options) public override string Name => options.Name; // Public methods. - public override async Task BuildIndexesAsync(ISchemaRegister schemaRegister, CancellationToken cancellationToken = default) + public override async Task BuildIndexesAsync(ISchemaRegistry schemaRegistry, CancellationToken cancellationToken = default) { var newIndexes = new List<(string name, CreateIndexModel createIndex)>(); @@ -79,7 +79,7 @@ public override async Task BuildIndexesAsync(ISchemaRegister schemaRegister, Can })); //referenced documents - var dependencies = DbContext.SchemaRegister.GetIdMemberDependenciesFromRootModel(typeof(TModel)); + var dependencies = DbContext.SchemaRegistry.GetIdMemberDependenciesFromRootModel(typeof(TModel)); var idPaths = dependencies .Select(dependency => dependency.MemberPathToString()) diff --git a/src/MongODM.Core/Repositories/GridFSRepository.cs b/src/MongODM.Core/Repositories/GridFSRepository.cs index 2fc1054f..d0c70700 100644 --- a/src/MongODM.Core/Repositories/GridFSRepository.cs +++ b/src/MongODM.Core/Repositories/GridFSRepository.cs @@ -51,7 +51,7 @@ public GridFSRepository(GridFSRepositoryOptions options) public override string Name => options.Name; // Methods. - public override Task BuildIndexesAsync(ISchemaRegister schemaRegister, CancellationToken cancellationToken = default) => Task.CompletedTask; + public override Task BuildIndexesAsync(ISchemaRegistry schemaRegistry, CancellationToken cancellationToken = default) => Task.CompletedTask; public virtual Task DownloadAsBytesAsync(string id, CancellationToken cancellationToken = default) => GridFSBucket.DownloadAsBytesAsync(ObjectId.Parse(id), null, cancellationToken); diff --git a/src/MongODM.Core/Repositories/IRepository.cs b/src/MongODM.Core/Repositories/IRepository.cs index edda7f9f..d6370bd7 100644 --- a/src/MongODM.Core/Repositories/IRepository.cs +++ b/src/MongODM.Core/Repositories/IRepository.cs @@ -29,7 +29,7 @@ public interface IRepository : IDbContextInitializable string Name { get; } Task BuildIndexesAsync( - ISchemaRegister schemaRegister, + ISchemaRegistry schemaRegistry, CancellationToken cancellationToken = default); Task CreateAsync( diff --git a/src/MongODM.Core/Repositories/IRepositoryRegister.cs b/src/MongODM.Core/Repositories/IRepositoryRegistry.cs similarity index 95% rename from src/MongODM.Core/Repositories/IRepositoryRegister.cs rename to src/MongODM.Core/Repositories/IRepositoryRegistry.cs index 1c41cac6..e070d0be 100644 --- a/src/MongODM.Core/Repositories/IRepositoryRegister.cs +++ b/src/MongODM.Core/Repositories/IRepositoryRegistry.cs @@ -17,7 +17,7 @@ namespace Etherna.MongODM.Core.Repositories { - public interface IRepositoryRegister : IDbContextInitializable + public interface IRepositoryRegistry : IDbContextInitializable { /// /// Model-Repository map for collection types. diff --git a/src/MongODM.Core/Repositories/RepositoryBase.cs b/src/MongODM.Core/Repositories/RepositoryBase.cs index 406195bf..8fcd83c9 100644 --- a/src/MongODM.Core/Repositories/RepositoryBase.cs +++ b/src/MongODM.Core/Repositories/RepositoryBase.cs @@ -49,7 +49,7 @@ public virtual void Initialize(IDbContext dbContext) public abstract string Name { get; } // Methods. - public abstract Task BuildIndexesAsync(ISchemaRegister schemaRegister, CancellationToken cancellationToken = default); + public abstract Task BuildIndexesAsync(ISchemaRegistry schemaRegistry, CancellationToken cancellationToken = default); public Task CreateAsync(object model, CancellationToken cancellationToken = default) => CreateAsync((TModel)model, cancellationToken); @@ -81,7 +81,7 @@ public virtual async Task DeleteAsync(TModel model, CancellationToken cancellati throw new ArgumentNullException(nameof(model)); // Process cascade delete. - var referencesIdsPaths = DbContext.SchemaRegister.GetIdMemberDependenciesFromRootModel(typeof(TModel)) + var referencesIdsPaths = DbContext.SchemaRegistry.GetIdMemberDependenciesFromRootModel(typeof(TModel)) .Where(d => d.UseCascadeDelete) .Where(d => d.EntityClassMapPath.Count() == 2) //ignore references of references .DistinctBy(d => d.FullPathToString()) @@ -169,7 +169,7 @@ private async Task CascadeDeleteMembersAsync(object currentModel, IEnumerable ModelCollectionRepositor return false; }); - // Initialize register. + // Initialize registry. _modelCollectionRepositoryMap = repos.ToDictionary( prop => ((ICollectionRepository)prop.GetValue(dbContext)).GetModelType, prop => (ICollectionRepository)prop.GetValue(dbContext)); @@ -103,7 +103,7 @@ public IReadOnlyDictionary ModelGridFSRepositoryMap return false; }); - //construct register + //construct registry _modelGridFSRepositoryMap = repos.ToDictionary( prop => ((IGridFSRepository)prop.GetValue(dbContext)).GetModelType, prop => (IGridFSRepository)prop.GetValue(dbContext)); diff --git a/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegistry.cs similarity index 99% rename from src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs rename to src/MongODM.Core/Serialization/Mapping/DiscriminatorRegistry.cs index 7dfc3ccf..218d572a 100644 --- a/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegistry.cs @@ -8,7 +8,7 @@ namespace Etherna.MongODM.Core.Serialization.Mapping { - public class DiscriminatorRegister : IDiscriminatorRegister + public class DiscriminatorRegistry : IDiscriminatorRegistry { // Fields. private readonly ReaderWriterLockSlim configLock = new(LockRecursionPolicy.SupportsRecursion); diff --git a/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs b/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegistry.cs similarity index 94% rename from src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs rename to src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegistry.cs index ee9bc1ba..eb77e408 100644 --- a/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegistry.cs @@ -4,7 +4,7 @@ namespace Etherna.MongODM.Core.Serialization.Mapping { - public interface IDiscriminatorRegister : IDbContextInitializable + public interface IDiscriminatorRegistry : IDbContextInitializable { void AddDiscriminator(Type type, BsonValue discriminator); diff --git a/src/MongODM.Core/Serialization/Mapping/ISchemaRegister.cs b/src/MongODM.Core/Serialization/Mapping/ISchemaRegistry.cs similarity index 97% rename from src/MongODM.Core/Serialization/Mapping/ISchemaRegister.cs rename to src/MongODM.Core/Serialization/Mapping/ISchemaRegistry.cs index f0cc59fe..b1a2c4de 100644 --- a/src/MongODM.Core/Serialization/Mapping/ISchemaRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/ISchemaRegistry.cs @@ -23,9 +23,9 @@ namespace Etherna.MongODM.Core.Serialization.Mapping { /// - /// Interface for implementation. + /// Interface for implementation. /// - public interface ISchemaRegister : IDbContextInitializable, IFreezableConfig + public interface ISchemaRegistry : IDbContextInitializable, IFreezableConfig { // Properties. /// diff --git a/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs b/src/MongODM.Core/Serialization/Mapping/SchemaRegistry.cs similarity index 98% rename from src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs rename to src/MongODM.Core/Serialization/Mapping/SchemaRegistry.cs index bacaddbc..add0a610 100644 --- a/src/MongODM.Core/Serialization/Mapping/SchemaRegister.cs +++ b/src/MongODM.Core/Serialization/Mapping/SchemaRegistry.cs @@ -28,7 +28,7 @@ namespace Etherna.MongODM.Core.Serialization.Mapping { - public class SchemaRegister : FreezableConfig, ISchemaRegister + public class SchemaRegistry : FreezableConfig, ISchemaRegistry { // Fields. private readonly Dictionary _schemas = new(); @@ -125,7 +125,7 @@ public BsonClassMap GetActiveClassMap(Type modelType) // Register classMap (if doesn't exist) with discriminator. defaultClassMapsCache.TryAdd(modelType, classMap); - dbContext.DiscriminatorRegister.AddDiscriminator(modelType, classMap.Discriminator); + dbContext.DiscriminatorRegistry.AddDiscriminator(modelType, classMap.Discriminator); return classMap; } @@ -224,12 +224,12 @@ protected override void FreezeAction() // Register active serializer. if (schema.ActiveSerializer != null) - ((BsonSerializerRegistry)dbContext.SerializerRegister).RegisterSerializer(schema.ModelType, schema.ActiveSerializer); + ((BsonSerializerRegistry)dbContext.SerializerRegistry).RegisterSerializer(schema.ModelType, schema.ActiveSerializer); // Register discriminators for all bson class maps. if (schema is IModelMapsSchema modelMapsSchema) foreach (var modelMap in modelMapsSchema.AllMapsDictionary.Values) - dbContext.DiscriminatorRegister.AddDiscriminator(modelMapsSchema.ModelType, modelMap.BsonClassMap.Discriminator); + dbContext.DiscriminatorRegistry.AddDiscriminator(modelMapsSchema.ModelType, modelMap.BsonClassMap.Discriminator); } // Specific for model maps schemas. diff --git a/src/MongODM.Core/Serialization/Serializers/ExtraElementsSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ExtraElementsSerializer.cs index 4a87530a..ba63af22 100644 --- a/src/MongODM.Core/Serialization/Serializers/ExtraElementsSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ExtraElementsSerializer.cs @@ -62,7 +62,7 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati } else { - var serializer = dbContext.SerializerRegister.GetSerializer(); + var serializer = dbContext.SerializerRegistry.GetSerializer(); serializer.Serialize(context, value); } } @@ -87,7 +87,7 @@ public TValue DeserializeValue( // Lookup for a serializer. if (serializer == null) { - serializer = dbContext.SerializerRegister.GetSerializer(); + serializer = dbContext.SerializerRegistry.GetSerializer(); } // Deserialize. diff --git a/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs index 30ea0a0e..65991cb9 100644 --- a/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs @@ -57,18 +57,18 @@ public ModelMapSerializer( } // Properties. - public IEnumerable AllChildClassMaps => dbContext.SchemaRegister.GetModelMapsSchema(typeof(TModel)) + public IEnumerable AllChildClassMaps => dbContext.SchemaRegistry.GetModelMapsSchema(typeof(TModel)) .AllMapsDictionary.Values.Select(map => map.BsonClassMap); public BsonClassMapSerializer DefaultBsonClassMapSerializer => - (BsonClassMapSerializer)dbContext.SchemaRegister.GetModelMapsSchema(typeof(TModel)).ActiveMap.BsonClassMapSerializer; + (BsonClassMapSerializer)dbContext.SchemaRegistry.GetModelMapsSchema(typeof(TModel)).ActiveMap.BsonClassMapSerializer; public IDiscriminatorConvention DiscriminatorConvention { get { if (_discriminatorConvention == null) - _discriminatorConvention = dbContext.DiscriminatorRegister.LookupDiscriminatorConvention(typeof(TModel)); + _discriminatorConvention = dbContext.DiscriminatorRegistry.LookupDiscriminatorConvention(typeof(TModel)); return _discriminatorConvention; } } @@ -89,7 +89,7 @@ public override TModel Deserialize(BsonDeserializationContext context, BsonDeser // Find pre-deserialization informations. //get actual type and schema var actualType = DiscriminatorConvention.GetActualType(context.Reader, args.NominalType); - var actualTypeSchema = dbContext.SchemaRegister.GetModelMapsSchema(actualType); + var actualTypeSchema = dbContext.SchemaRegistry.GetModelMapsSchema(actualType); //deserialize on document var bsonDocument = BsonDocumentSerializer.Instance.Deserialize(context, args); @@ -196,7 +196,7 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati // Get default schema. var actualType = value.GetType(); - var modelMapsSchema = dbContext.SchemaRegister.GetModelMapsSchema(actualType); + var modelMapsSchema = dbContext.SchemaRegistry.GetModelMapsSchema(actualType); // Serialize. modelMapsSchema.ActiveBsonClassMapSerializer.Serialize(localContext, args, value); @@ -210,7 +210,7 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati * don't have to replace it with the one wrong of the basic collection model type. */ if (!bsonDocument.Contains(modelMapVersionOptions.ElementName)) - bsonDocument.InsertAt(0, dbContext.SchemaRegister.GetActiveModelMapIdBsonElement(actualType)); + bsonDocument.InsertAt(0, dbContext.SchemaRegistry.GetActiveModelMapIdBsonElement(actualType)); //add version if (documentSemVerOptions.WriteInDocuments && bsonWriter.IsRootDocument) diff --git a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs index 33867cbc..cd587069 100644 --- a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs @@ -90,7 +90,7 @@ public IDiscriminatorConvention DiscriminatorConvention get { if (_discriminatorConvention == null) - _discriminatorConvention = dbContext.DiscriminatorRegister.LookupDiscriminatorConvention(typeof(TModelBase)); + _discriminatorConvention = dbContext.DiscriminatorRegistry.LookupDiscriminatorConvention(typeof(TModelBase)); return _discriminatorConvention; } } diff --git a/src/MongODM.Core/Tasks/MigrateDbContextTask.cs b/src/MongODM.Core/Tasks/MigrateDbContextTask.cs index b0520c71..387ed69f 100644 --- a/src/MongODM.Core/Tasks/MigrateDbContextTask.cs +++ b/src/MongODM.Core/Tasks/MigrateDbContextTask.cs @@ -69,14 +69,14 @@ public async Task RunAsync(string dbMigrationOpId, string taskId) } // Build indexes. - foreach (var repository in dbContext.RepositoryRegister.ModelCollectionRepositoryMap.Values) + foreach (var repository in dbContext.RepositoryRegistry.ModelCollectionRepositoryMap.Values) { dbMigrationOp.AddLog(new IndexMigrationLog( repository.Name, MigrationLogBase.ExecutionState.Executing)); await dbContext.SaveChangesAsync().ConfigureAwait(false); - await repository.BuildIndexesAsync(dbContext.SchemaRegister).ConfigureAwait(false); + await repository.BuildIndexesAsync(dbContext.SchemaRegistry).ConfigureAwait(false); dbMigrationOp.AddLog(new IndexMigrationLog( repository.Name, diff --git a/src/MongODM.Core/Tasks/UpdateDocDependenciesTask.cs b/src/MongODM.Core/Tasks/UpdateDocDependenciesTask.cs index 09bce9fe..9eb20a01 100644 --- a/src/MongODM.Core/Tasks/UpdateDocDependenciesTask.cs +++ b/src/MongODM.Core/Tasks/UpdateDocDependenciesTask.cs @@ -51,10 +51,10 @@ public async Task RunAsync( // Get repository. /* Ignore document update if doesn't exists a collection that can handle its type. */ - if (!dbContext.RepositoryRegister.ModelCollectionRepositoryMap.ContainsKey(typeof(TModel))) + if (!dbContext.RepositoryRegistry.ModelCollectionRepositoryMap.ContainsKey(typeof(TModel))) return; - var repository = (ICollectionRepository)dbContext.RepositoryRegister.ModelCollectionRepositoryMap[typeof(TModel)]; + var repository = (ICollectionRepository)dbContext.RepositoryRegistry.ModelCollectionRepositoryMap[typeof(TModel)]; // Update models. HashSet upgradedDocumentsId = new(); diff --git a/src/MongODM.Core/Utility/DbMaintainer.cs b/src/MongODM.Core/Utility/DbMaintainer.cs index 5ee47106..0a1ef447 100644 --- a/src/MongODM.Core/Utility/DbMaintainer.cs +++ b/src/MongODM.Core/Utility/DbMaintainer.cs @@ -55,12 +55,12 @@ public void OnUpdatedModel(IAuditable updatedModel, TKey modelId) // Find all possible coinvolted member maps with changes. Keep only referenced members var updatedMembers = updatedModel.ChangedMembers; - var referenceMemberMaps = updatedMembers.SelectMany(memberInfo => dbContext.SchemaRegister.GetMemberDependenciesFromMemberInfo(memberInfo)) + var referenceMemberMaps = updatedMembers.SelectMany(memberInfo => dbContext.SchemaRegistry.GetMemberDependenciesFromMemberInfo(memberInfo)) .Where(memberMap => memberMap.IsEntityReferenceMember); // Group by root model type, and select only model types related to a collections. foreach (var dependencyGroup in referenceMemberMaps.GroupBy(memberMap => memberMap.RootModelMap.ModelType) - .Where(group => dbContext.RepositoryRegister.ModelCollectionRepositoryMap.ContainsKey(group.Key))) + .Where(group => dbContext.RepositoryRegistry.ModelCollectionRepositoryMap.ContainsKey(group.Key))) { // Extract only id paths to referenced entities. var idPaths = dependencyGroup diff --git a/test/MongODM.Core.Tests/ModelMapSerializerTest.cs b/test/MongODM.Core.Tests/ModelMapSerializerTest.cs index 92e491bd..282e5b3e 100644 --- a/test/MongODM.Core.Tests/ModelMapSerializerTest.cs +++ b/test/MongODM.Core.Tests/ModelMapSerializerTest.cs @@ -80,17 +80,17 @@ public SerializationTestElement( // Fields. private readonly Mock dbCacheMock = new(); private readonly Mock dbContextMock = new(); - private readonly Mock discriminatorRegisterMock = new(); + private readonly Mock discriminatorRegistryMock = new(); private readonly DocumentSemVerOptions documentSemVerOptions = new(); private readonly Mock modelMapsSchemaMock = new(); private readonly ModelMapVersionOptions modelMapVersionOptions = new(); - private readonly Mock schemaRegisterMock = new(); + private readonly Mock schemaRegistryMock = new(); private readonly Mock serializerModifierAccessorMock = new(); // Constructor. public ModelMapSerializerTest() { - discriminatorRegisterMock.Setup(r => r.LookupDiscriminatorConvention(It.IsAny())) + discriminatorRegistryMock.Setup(r => r.LookupDiscriminatorConvention(It.IsAny())) .Returns(() => new HierarchicalProxyTolerantDiscriminatorConvention(dbContextMock.Object, "_t")); dbCacheMock.Setup(c => c.LoadedModels.ContainsKey(It.IsAny())) @@ -98,18 +98,18 @@ public ModelMapSerializerTest() dbContextMock.Setup(c => c.DbCache) .Returns(() => dbCacheMock.Object); - dbContextMock.Setup(c => c.DiscriminatorRegister) - .Returns(() => discriminatorRegisterMock.Object); + dbContextMock.Setup(c => c.DiscriminatorRegistry) + .Returns(() => discriminatorRegistryMock.Object); dbContextMock.Setup(c => c.Options.DocumentSemVer) .Returns(() => documentSemVerOptions); dbContextMock.Setup(c => c.Options.ModelMapVersion) .Returns(() => modelMapVersionOptions); - dbContextMock.Setup(c => c.SchemaRegister) - .Returns(() => schemaRegisterMock.Object); + dbContextMock.Setup(c => c.SchemaRegistry) + .Returns(() => schemaRegistryMock.Object); dbContextMock.Setup(c => c.SerializerModifierAccessor) .Returns(() => serializerModifierAccessorMock.Object); - schemaRegisterMock.Setup(sr => sr.GetModelMapsSchema(typeof(FakeModel))) + schemaRegistryMock.Setup(sr => sr.GetModelMapsSchema(typeof(FakeModel))) .Returns(() => modelMapsSchemaMock.Object); } @@ -304,7 +304,7 @@ public void Serialize(SerializationTestElement test) modelMapsSchemaMock.Setup(s => s.ActiveMap.Id) .Returns("mapId"); - schemaRegisterMock.Setup(sr => sr.GetActiveModelMapIdBsonElement(typeof(FakeModel))) + schemaRegistryMock.Setup(sr => sr.GetActiveModelMapIdBsonElement(typeof(FakeModel))) .Returns(new BsonElement("_m", new BsonString("mapId"))); // Action diff --git a/test/MongODM.Core.Tests/ReferenceableInterceptorTest.cs b/test/MongODM.Core.Tests/ReferenceableInterceptorTest.cs index 4be9745d..169b09a9 100644 --- a/test/MongODM.Core.Tests/ReferenceableInterceptorTest.cs +++ b/test/MongODM.Core.Tests/ReferenceableInterceptorTest.cs @@ -39,7 +39,7 @@ public ReferenceableInterceptorTest() repositoryMock = new Mock>(); dbContextMock = new Mock(); - dbContextMock.Setup(c => c.RepositoryRegister.ModelRepositoryMap) + dbContextMock.Setup(c => c.RepositoryRegistry.ModelRepositoryMap) .Returns(() => new Dictionary { [typeof(FakeModel)] = repositoryMock.Object From e1aca237eec9976fad1b5803ac31ce0728a5c0ae Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Mon, 13 Dec 2021 16:10:02 +0100 Subject: [PATCH 38/78] Added MongodmDbSeedingException --- src/MongODM.Core/DbContext.cs | 4 +++- .../Exceptions/MongodmDbSeedingException.cs | 19 +++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) create mode 100644 src/MongODM.Core/Exceptions/MongodmDbSeedingException.cs diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index a5f39f01..b6a84b22 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -17,6 +17,7 @@ using Etherna.MongoDB.Driver.Linq; using Etherna.MongODM.Core.Domain.ModelMaps; using Etherna.MongODM.Core.Domain.Models; +using Etherna.MongODM.Core.Exceptions; using Etherna.MongODM.Core.Migration; using Etherna.MongODM.Core.Options; using Etherna.MongODM.Core.ProxyModels; @@ -200,7 +201,8 @@ public async Task SeedIfNeededAsync() return false; // Seed. - await SeedAsync().ConfigureAwait(false); + try { await SeedAsync().ConfigureAwait(false); } + catch (Exception e) { throw new MongodmDbSeedingException($"Error seeding {GetType().Name} dbContext", e); } // Report operation. var seedOperation = new SeedOperation(this); diff --git a/src/MongODM.Core/Exceptions/MongodmDbSeedingException.cs b/src/MongODM.Core/Exceptions/MongodmDbSeedingException.cs new file mode 100644 index 00000000..c9d0a045 --- /dev/null +++ b/src/MongODM.Core/Exceptions/MongodmDbSeedingException.cs @@ -0,0 +1,19 @@ +using System; + +namespace Etherna.MongODM.Core.Exceptions +{ + public class MongodmDbSeedingException : Exception + { + public MongodmDbSeedingException() + { + } + + public MongodmDbSeedingException(string message) : base(message) + { + } + + public MongodmDbSeedingException(string message, Exception innerException) : base(message, innerException) + { + } + } +} From 07eafba39d88baf0b4b239a6d3be568dcbf720f9 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Mon, 13 Dec 2021 17:36:23 +0100 Subject: [PATCH 39/78] Implemented IsSeeded property --- src/MongODM.Core/DbContext.cs | 58 ++++++++++++++++++++++++++++++++-- src/MongODM.Core/IDbContext.cs | 5 +++ 2 files changed, 60 insertions(+), 3 deletions(-) diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index b6a84b22..71d2be2b 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -38,8 +38,10 @@ namespace Etherna.MongODM.Core public abstract class DbContext : IDbContext, IDbContextBuilder { // Fields. + private bool? _isSeeded; private BsonSerializerRegistry _serializerRegistry = default!; private bool isInitialized; + private readonly ReaderWriterLockSlim seedingLock = new(LockRecursionPolicy.SupportsRecursion); // Constructor and initializer. protected DbContext() { } @@ -128,6 +130,55 @@ public async Task InitializeAsync( public IDiscriminatorRegistry DiscriminatorRegistry { get; private set; } = default!; public virtual IEnumerable DocumentMigrationList { get; } = Array.Empty(); public string Identifier => Options?.Identifier ?? GetType().Name; + public bool IsSeeded + { + get + { + // Try to read cached. + seedingLock.EnterReadLock(); + try + { + if (_isSeeded.HasValue) + return _isSeeded.Value; + } + finally + { + seedingLock.ExitReadLock(); + } + + // Get seeding state from db. + seedingLock.EnterWriteLock(); + try + { + if (!_isSeeded.HasValue) + { + var task = DbOperations.QueryElementsAsync(elements => + elements.OfType() + .AnyAsync(sop => sop.DbContextName == Identifier)); + task.Wait(); + _isSeeded = task.Result; + } + + return _isSeeded.Value; + } + finally + { + seedingLock.ExitWriteLock(); + } + } + private set + { + seedingLock.EnterWriteLock(); + try + { + _isSeeded = value; + } + finally + { + seedingLock.ExitWriteLock(); + } + } + } public SemanticVersion LibraryVersion { get; private set; } = default!; public IDbContextOptions Options { get; private set; } = default!; public IProxyGenerator ProxyGenerator { get; private set; } = default!; @@ -195,9 +246,7 @@ public virtual async Task SaveChangesAsync(CancellationToken cancellationToken = public async Task SeedIfNeededAsync() { // Check if already seeded. - if (await DbOperations.QueryElementsAsync(elements => - elements.OfType() - .AnyAsync(sop => sop.DbContextName == Identifier)).ConfigureAwait(false)) + if (IsSeeded) return false; // Seed. @@ -208,6 +257,9 @@ public async Task SeedIfNeededAsync() var seedOperation = new SeedOperation(this); await DbOperations.CreateAsync(seedOperation).ConfigureAwait(false); + // Cache as seeded. + IsSeeded = true; + return true; } diff --git a/src/MongODM.Core/IDbContext.cs b/src/MongODM.Core/IDbContext.cs index 7d33f520..6f65c2ab 100644 --- a/src/MongODM.Core/IDbContext.cs +++ b/src/MongODM.Core/IDbContext.cs @@ -80,6 +80,11 @@ public interface IDbContext /// string Identifier { get; } + /// + /// True if it has been seeded. + /// + bool IsSeeded { get; } + /// /// Current MongODM library version. /// From 382b21c831c17198d4b21f7c21ad5a1181b3704d Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Mon, 13 Dec 2021 23:10:16 +0100 Subject: [PATCH 40/78] Implemented DbContextsSeedingMiddleware Updated db seeding process --- samples/AspNetCoreSample/Startup.cs | 1 - .../ApplicationBuilderExtensions.cs | 14 +++++ .../ServiceCollectionExtensions.cs | 3 +- .../DbContextsSeedingMiddleware.cs | 48 +++++++++++++++++ .../MongODMConfiguration.cs | 3 +- src/MongODM.Core/DbContext.cs | 51 +++++++++++-------- src/MongODM.Core/IDbContextBuilder.cs | 3 +- src/MongODM.Core/Options/DbContextOptions.cs | 1 - src/MongODM.Core/Options/IDbContextOptions.cs | 1 - .../ServiceCollectionExtensions.cs | 0 10 files changed, 96 insertions(+), 29 deletions(-) create mode 100644 src/MongODM.AspNetCore/Extensions/ApplicationBuilderExtensions.cs rename src/MongODM.AspNetCore/{ => Extensions}/ServiceCollectionExtensions.cs (98%) create mode 100644 src/MongODM.AspNetCore/Middlewares/DbContextsSeedingMiddleware.cs rename src/MongODM/{ => Extensions}/ServiceCollectionExtensions.cs (100%) diff --git a/samples/AspNetCoreSample/Startup.cs b/samples/AspNetCoreSample/Startup.cs index 4d119c5a..ab67c0ea 100644 --- a/samples/AspNetCoreSample/Startup.cs +++ b/samples/AspNetCoreSample/Startup.cs @@ -13,7 +13,6 @@ // limitations under the License. using Etherna.MongODM.AspNetCore.UI; -using Etherna.MongODM.AspNetCoreSample.Models; using Etherna.MongODM.AspNetCoreSample.Persistence; using Hangfire; using Microsoft.AspNetCore.Builder; diff --git a/src/MongODM.AspNetCore/Extensions/ApplicationBuilderExtensions.cs b/src/MongODM.AspNetCore/Extensions/ApplicationBuilderExtensions.cs new file mode 100644 index 00000000..d32fe1e5 --- /dev/null +++ b/src/MongODM.AspNetCore/Extensions/ApplicationBuilderExtensions.cs @@ -0,0 +1,14 @@ +using Etherna.MongODM.AspNetCore.Middlewares; +using Microsoft.AspNetCore.Builder; + +namespace Etherna.MongODM +{ + public static class ApplicationBuilderExtensions + { + public static IApplicationBuilder UseDbContextsSeeding( + this IApplicationBuilder builder) + { + return builder.UseMiddleware(); + } + } +} diff --git a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs b/src/MongODM.AspNetCore/Extensions/ServiceCollectionExtensions.cs similarity index 98% rename from src/MongODM.AspNetCore/ServiceCollectionExtensions.cs rename to src/MongODM.AspNetCore/Extensions/ServiceCollectionExtensions.cs index dc72bc9c..67c7f3d5 100644 --- a/src/MongODM.AspNetCore/ServiceCollectionExtensions.cs +++ b/src/MongODM.AspNetCore/Extensions/ServiceCollectionExtensions.cs @@ -16,6 +16,7 @@ using Etherna.MongoDB.Bson; using Etherna.MongoDB.Bson.Serialization; using Etherna.MongoDB.Bson.Serialization.Conventions; +using Etherna.MongODM.AspNetCore; using Etherna.MongODM.Core; using Etherna.MongODM.Core.Options; using Etherna.MongODM.Core.ProxyModels; @@ -28,7 +29,7 @@ using Microsoft.Extensions.DependencyInjection.Extensions; using System; -namespace Etherna.MongODM.AspNetCore +namespace Etherna.MongODM { public static class ServiceCollectionExtensions { diff --git a/src/MongODM.AspNetCore/Middlewares/DbContextsSeedingMiddleware.cs b/src/MongODM.AspNetCore/Middlewares/DbContextsSeedingMiddleware.cs new file mode 100644 index 00000000..80c03bf4 --- /dev/null +++ b/src/MongODM.AspNetCore/Middlewares/DbContextsSeedingMiddleware.cs @@ -0,0 +1,48 @@ +using Etherna.MongODM.Core; +using Etherna.MongODM.Core.Options; +using Microsoft.AspNetCore.Http; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; + +namespace Etherna.MongODM.AspNetCore.Middlewares +{ + public class DbContextsSeedingMiddleware + { + // Fields. + private readonly RequestDelegate next; + private readonly IEnumerable dbContexts; + + // Constructor. + public DbContextsSeedingMiddleware( + RequestDelegate next, + IOptions mongODMOptions, + IServiceProvider serviceProvider) + { + if (mongODMOptions is null) + throw new ArgumentNullException(nameof(mongODMOptions)); + + this.next = next; + var dbContextTypes = mongODMOptions.Value.DbContextTypes; + + // Get dbcontext instances (cache them). + dbContexts = dbContextTypes.Select(type => (IDbContext)serviceProvider.GetRequiredService(type)) + .ToList(); + } + + // Methods. + public async Task InvokeAsync(HttpContext context) + { + // Seed all dbcontexts. + foreach (var dbContext in dbContexts) + if (!dbContext.IsSeeded) + await dbContext.SeedIfNeededAsync().ConfigureAwait(false); + + // Call the next delegate/middleware in the pipeline. + await next(context).ConfigureAwait(false); + } + } +} diff --git a/src/MongODM.AspNetCore/MongODMConfiguration.cs b/src/MongODM.AspNetCore/MongODMConfiguration.cs index 2b8cd56e..5b423f74 100644 --- a/src/MongODM.AspNetCore/MongODMConfiguration.cs +++ b/src/MongODM.AspNetCore/MongODMConfiguration.cs @@ -114,8 +114,7 @@ public IMongODMConfiguration AddDbContext( var dbContext = dbContextCreator(sp); // Initialize instance. - var task = dbContext.InitializeAsync(dependencies, options); - task.Wait(); + dbContext.Initialize(dependencies, options); return dbContext; }); diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index 71d2be2b..1ab14df2 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -41,11 +41,12 @@ public abstract class DbContext : IDbContext, IDbContextBuilder private bool? _isSeeded; private BsonSerializerRegistry _serializerRegistry = default!; private bool isInitialized; - private readonly ReaderWriterLockSlim seedingLock = new(LockRecursionPolicy.SupportsRecursion); + private readonly ReaderWriterLockSlim isSeededLock = new(); //support read/write locks + private readonly SemaphoreSlim seedingSemaphore = new(1, 1); //support async/await // Constructor and initializer. protected DbContext() { } - public async Task InitializeAsync( + public void Initialize( IDbDependencies dependencies, IDbContextOptions options) { @@ -108,10 +109,6 @@ public async Task InitializeAsync( // Build and freeze schema registry. SchemaRegistry.Freeze(); - // Initialize data. - if (!Options.DisableAutomaticSeed) - await SeedIfNeededAsync().ConfigureAwait(false); - // Set as initialized. isInitialized = true; } @@ -135,7 +132,7 @@ public bool IsSeeded get { // Try to read cached. - seedingLock.EnterReadLock(); + isSeededLock.EnterReadLock(); try { if (_isSeeded.HasValue) @@ -143,11 +140,11 @@ public bool IsSeeded } finally { - seedingLock.ExitReadLock(); + isSeededLock.ExitReadLock(); } // Get seeding state from db. - seedingLock.EnterWriteLock(); + isSeededLock.EnterWriteLock(); try { if (!_isSeeded.HasValue) @@ -163,19 +160,19 @@ public bool IsSeeded } finally { - seedingLock.ExitWriteLock(); + isSeededLock.ExitWriteLock(); } } private set { - seedingLock.EnterWriteLock(); + isSeededLock.EnterWriteLock(); try { _isSeeded = value; } finally { - seedingLock.ExitWriteLock(); + isSeededLock.ExitWriteLock(); } } } @@ -249,18 +246,30 @@ public async Task SeedIfNeededAsync() if (IsSeeded) return false; - // Seed. - try { await SeedAsync().ConfigureAwait(false); } - catch (Exception e) { throw new MongodmDbSeedingException($"Error seeding {GetType().Name} dbContext", e); } + await seedingSemaphore.WaitAsync().ConfigureAwait(false); + try + { + // Check again if seeded. + if (IsSeeded) + return false; + + // Seed. + try { await SeedAsync().ConfigureAwait(false); } + catch (Exception e) { throw new MongodmDbSeedingException($"Error seeding {GetType().Name} dbContext", e); } - // Report operation. - var seedOperation = new SeedOperation(this); - await DbOperations.CreateAsync(seedOperation).ConfigureAwait(false); + // Report operation. + var seedOperation = new SeedOperation(this); + await DbOperations.CreateAsync(seedOperation).ConfigureAwait(false); - // Cache as seeded. - IsSeeded = true; + // Cache as seeded. + IsSeeded = true; - return true; + return true; + } + finally + { + seedingSemaphore.Release(); + } } public Task StartSessionAsync(CancellationToken cancellationToken = default) => diff --git a/src/MongODM.Core/IDbContextBuilder.cs b/src/MongODM.Core/IDbContextBuilder.cs index 3b23e1f6..8bfd674a 100644 --- a/src/MongODM.Core/IDbContextBuilder.cs +++ b/src/MongODM.Core/IDbContextBuilder.cs @@ -1,10 +1,9 @@ using Etherna.MongODM.Core.Options; -using System.Threading.Tasks; namespace Etherna.MongODM.Core { public interface IDbContextBuilder { - Task InitializeAsync(IDbDependencies dependencies, IDbContextOptions options); + void Initialize(IDbDependencies dependencies, IDbContextOptions options); } } diff --git a/src/MongODM.Core/Options/DbContextOptions.cs b/src/MongODM.Core/Options/DbContextOptions.cs index 0c8e0182..2b591a6c 100644 --- a/src/MongODM.Core/Options/DbContextOptions.cs +++ b/src/MongODM.Core/Options/DbContextOptions.cs @@ -23,7 +23,6 @@ public class DbContextOptions : IDbContextOptions public string DbName => ConnectionString.Split('?')[0] .Split('/').Last(); public string DbOperationsCollectionName { get; set; } = "_db_ops"; - public bool DisableAutomaticSeed { get; set; } public DocumentSemVerOptions DocumentSemVer { get; set; } = new DocumentSemVerOptions(); public string? Identifier { get; set; } public ModelMapVersionOptions ModelMapVersion { get; set; } = new ModelMapVersionOptions(); diff --git a/src/MongODM.Core/Options/IDbContextOptions.cs b/src/MongODM.Core/Options/IDbContextOptions.cs index 0248dd44..b61dc7fc 100644 --- a/src/MongODM.Core/Options/IDbContextOptions.cs +++ b/src/MongODM.Core/Options/IDbContextOptions.cs @@ -19,7 +19,6 @@ public interface IDbContextOptions public string ConnectionString { get; } public string DbName { get; } public string DbOperationsCollectionName { get; } - public bool DisableAutomaticSeed { get; } public DocumentSemVerOptions DocumentSemVer { get; } public string? Identifier { get; } public ModelMapVersionOptions ModelMapVersion { get; } diff --git a/src/MongODM/ServiceCollectionExtensions.cs b/src/MongODM/Extensions/ServiceCollectionExtensions.cs similarity index 100% rename from src/MongODM/ServiceCollectionExtensions.cs rename to src/MongODM/Extensions/ServiceCollectionExtensions.cs From a15e3325aa04dd3d235be63fbbd52320e3e6b9ce Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sat, 25 Dec 2021 00:14:55 +0100 Subject: [PATCH 41/78] Implementing MODM-108 solution --- .../Extensions/ServiceCollectionExtensions.cs | 11 +++++ ...calProxyTolerantDiscriminatorConvention.cs | 45 ++++++++++++++++--- src/MongODM.Core/DbContext.cs | 9 +++- src/MongODM.Core/MongODM.Core.csproj | 4 +- 4 files changed, 60 insertions(+), 9 deletions(-) diff --git a/src/MongODM.AspNetCore/Extensions/ServiceCollectionExtensions.cs b/src/MongODM.AspNetCore/Extensions/ServiceCollectionExtensions.cs index 67c7f3d5..cad5c257 100644 --- a/src/MongODM.AspNetCore/Extensions/ServiceCollectionExtensions.cs +++ b/src/MongODM.AspNetCore/Extensions/ServiceCollectionExtensions.cs @@ -12,12 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.ExecContext; using Etherna.ExecContext.AspNetCore; using Etherna.MongoDB.Bson; using Etherna.MongoDB.Bson.Serialization; using Etherna.MongoDB.Bson.Serialization.Conventions; using Etherna.MongODM.AspNetCore; using Etherna.MongODM.Core; +using Etherna.MongODM.Core.Conventions; using Etherna.MongODM.Core.Options; using Etherna.MongODM.Core.ProxyModels; using Etherna.MongODM.Core.Repositories; @@ -66,6 +68,15 @@ public static IMongODMConfiguration AddMongODM( taskRunnerBuilder.SetMongODMOptions(options); }); + /* Register discriminator convention on typeof(object) because we need a method to handle + * default returned instance from static calls to BsonSerializer.LookupDiscriminatorConvention(Type). + * Several points internal to drivers invoke this method, and we can't avoid it. We need to set the default. + */ + var sp = services.BuildServiceProvider(); + var execContext = sp.GetRequiredService(); + BsonSerializer.RegisterDiscriminatorConvention(typeof(object), + new HierarchicalProxyTolerantDiscriminatorConvention("_t", execContext)); + services.AddExecutionContext(); services.TryAddSingleton(); diff --git a/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs b/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs index 629fac12..93da0071 100644 --- a/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs +++ b/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.ExecContext; using Etherna.MongoDB.Bson; using Etherna.MongoDB.Bson.IO; using Etherna.MongoDB.Bson.Serialization; @@ -26,20 +27,52 @@ namespace Etherna.MongODM.Core.Conventions public class HierarchicalProxyTolerantDiscriminatorConvention : IDiscriminatorConvention { // Fields. - private readonly IDbContext dbContext; + private readonly IDbContext? _dbContext; //remove nullability with constructors that don't ask it, when will be possible + private readonly IExecutionContext? executionContext; // Constructors. public HierarchicalProxyTolerantDiscriminatorConvention( IDbContext dbContext, string elementName) { - this.dbContext = dbContext; + _dbContext = dbContext; ElementName = elementName ?? throw new ArgumentNullException(nameof(elementName)); if (elementName.IndexOf('\0') != -1) throw new ArgumentException("Element names cannot contain nulls.", nameof(elementName)); } + /// + /// Only needed for static registration on , used when dbcontext is not available. + /// Remove when static call will be removed. + /// + /// Discriminator element name + public HierarchicalProxyTolerantDiscriminatorConvention( + string elementName, + IExecutionContext executionContext) + { + ElementName = elementName ?? throw new ArgumentNullException(nameof(elementName)); + if (elementName.IndexOf('\0') != -1) + throw new ArgumentException("Element names cannot contain nulls.", nameof(elementName)); + + this.executionContext = executionContext; + } + + public IDbContext DbContext + { + get + { + if (_dbContext is not null) + return _dbContext; + + /* If we didn't injected a dbContext, this is an instance retrieved from a static invoke. + * Try to find it from execution contenxt. */ + if (executionContext is null) + throw new InvalidOperationException(); + + return Core.DbContext.GetCurrentDbContext(executionContext); + } + } public string ElementName { get; } // Methods. @@ -53,7 +86,7 @@ public Type GetActualType(IBsonReader bsonReader, Type nominalType) if (bsonType == BsonType.Document) { //we can skip looking for a discriminator if nominalType has no discriminated sub types - if (dbContext.DiscriminatorRegistry.IsTypeDiscriminated(nominalType)) + if (DbContext.DiscriminatorRegistry.IsTypeDiscriminated(nominalType)) { var bookmark = bsonReader.GetBookmark(); bsonReader.ReadStartDocument(); @@ -66,7 +99,7 @@ public Type GetActualType(IBsonReader bsonReader, Type nominalType) { discriminator = discriminator.AsBsonArray.Last(); //last item is leaf class discriminator } - actualType = dbContext.DiscriminatorRegistry.LookupActualType(nominalType, discriminator); + actualType = DbContext.DiscriminatorRegistry.LookupActualType(nominalType, discriminator); } bsonReader.ReturnToBookmark(bookmark); return actualType; @@ -85,10 +118,10 @@ public Type GetActualType(IBsonReader bsonReader, Type nominalType) public BsonValue? GetDiscriminator(Type nominalType, Type actualType) { // Remove proxy type. - actualType = dbContext.ProxyGenerator.PurgeProxyType(actualType); + actualType = DbContext.ProxyGenerator.PurgeProxyType(actualType); // Find active class map for model type. - var classMap = dbContext.SchemaRegistry.GetActiveClassMap(actualType); + var classMap = DbContext.SchemaRegistry.GetActiveClassMap(actualType); // Get discriminator from class map. if (actualType != nominalType || classMap.DiscriminatorIsRequired || classMap.HasRootClass) diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index 1ab14df2..e3e91fa2 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.ExecContext; using Etherna.MongoDB.Bson.Serialization; using Etherna.MongoDB.Driver; using Etherna.MongoDB.Driver.Linq; @@ -279,7 +280,13 @@ public Task StartSessionAsync(CancellationToken cancellati protected virtual Task SeedAsync() => Task.CompletedTask; - // Helpers. + // Internal static methods. + internal static IDbContext GetCurrentDbContext(IExecutionContext executionContext) + { + throw new NotImplementedException(); + } + + // Private helpers. private void InitializeSerializerRegistry() { //order matters. It's in reverse order of how they'll get consumed diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index 498dbe70..17a648e8 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -23,8 +23,8 @@ - - + + all From d70ea86dbfdc6db1d9b877c775dcff93ff2a15da Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sat, 25 Dec 2021 21:10:18 +0100 Subject: [PATCH 42/78] Removed unused class HttpContextExecutionContext --- .../HttpContextExecutionContext.cs | 35 ------------------- 1 file changed, 35 deletions(-) delete mode 100644 src/MongODM.AspNetCore/HttpContextExecutionContext.cs diff --git a/src/MongODM.AspNetCore/HttpContextExecutionContext.cs b/src/MongODM.AspNetCore/HttpContextExecutionContext.cs deleted file mode 100644 index 62b7f85d..00000000 --- a/src/MongODM.AspNetCore/HttpContextExecutionContext.cs +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright 2020-present Etherna Sagl -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -using Etherna.ExecContext; -using Microsoft.AspNetCore.Http; -using System.Collections.Generic; - -namespace Etherna.MongODM.AspNetCore -{ - public class HttpContextExecutionContext : IExecutionContext - { - // Fields. - private readonly IHttpContextAccessor httpContextAccessor; - - // Constructors. - public HttpContextExecutionContext(IHttpContextAccessor httpContextAccessor) - { - this.httpContextAccessor = httpContextAccessor; - } - - // Properties. - public IDictionary? Items => httpContextAccessor?.HttpContext?.Items; - } -} From 3f51c5c8a335eea76ae8f742468f0f9f1ae22f43 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sat, 25 Dec 2021 22:52:07 +0100 Subject: [PATCH 43/78] Implemented DbContextExecutionContextHandler --- src/MongODM.AspNetCore/DbDependencies.cs | 4 ++ src/MongODM.Core/DbContext.cs | 8 +-- src/MongODM.Core/IDbContext.cs | 6 ++ src/MongODM.Core/IDbDependencies.cs | 2 + .../DbContextExecutionContextHandler.cs | 62 +++++++++++++++++++ 5 files changed, 76 insertions(+), 6 deletions(-) create mode 100644 src/MongODM.Core/Utility/DbContextExecutionContextHandler.cs diff --git a/src/MongODM.AspNetCore/DbDependencies.cs b/src/MongODM.AspNetCore/DbDependencies.cs index bc1107ed..fc416ea7 100644 --- a/src/MongODM.AspNetCore/DbDependencies.cs +++ b/src/MongODM.AspNetCore/DbDependencies.cs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.ExecContext; using Etherna.MongoDB.Bson.Serialization; using Etherna.MongODM.Core; using Etherna.MongODM.Core.Options; @@ -33,6 +34,7 @@ public DbDependencies( IDbMaintainer dbMaintainer, IDbMigrationManager dbContextMigrationManager, IDiscriminatorRegistry discriminatorRegistry, + IExecutionContext executionContext, IOptions mongODMOptions, IProxyGenerator proxyGenerator, IRepositoryRegistry repositoryRegistry, @@ -46,6 +48,7 @@ public DbDependencies( DbMaintainer = dbMaintainer; DbMigrationManager = dbContextMigrationManager; DiscriminatorRegistry = discriminatorRegistry; + ExecutionContext = executionContext; MongODMOptions = mongODMOptions.Value; SchemaRegistry = schemaRegistry; ProxyGenerator = proxyGenerator; @@ -58,6 +61,7 @@ public DbDependencies( public IDbMaintainer DbMaintainer { get; } public IDbMigrationManager DbMigrationManager { get; } public IDiscriminatorRegistry DiscriminatorRegistry { get; } + public IExecutionContext ExecutionContext { get; } public MongODMOptions MongODMOptions { get; } public IProxyGenerator ProxyGenerator { get; } public IRepositoryRegistry RepositoryRegistry { get; } diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index e3e91fa2..6844ec5d 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -64,6 +64,7 @@ public void Initialize( DbMigrationManager = dependencies.DbMigrationManager; DbOperations = new CollectionRepository(options.DbOperationsCollectionName); DiscriminatorRegistry = dependencies.DiscriminatorRegistry; + ExecutionContext = dependencies.ExecutionContext; LibraryVersion = typeof(DbContext) .GetTypeInfo() .Assembly @@ -127,6 +128,7 @@ public void Initialize( public ICollectionRepository DbOperations { get; private set; } = default!; public IDiscriminatorRegistry DiscriminatorRegistry { get; private set; } = default!; public virtual IEnumerable DocumentMigrationList { get; } = Array.Empty(); + public IExecutionContext ExecutionContext { get; private set; } = default!; public string Identifier => Options?.Identifier ?? GetType().Name; public bool IsSeeded { @@ -280,12 +282,6 @@ public Task StartSessionAsync(CancellationToken cancellati protected virtual Task SeedAsync() => Task.CompletedTask; - // Internal static methods. - internal static IDbContext GetCurrentDbContext(IExecutionContext executionContext) - { - throw new NotImplementedException(); - } - // Private helpers. private void InitializeSerializerRegistry() { diff --git a/src/MongODM.Core/IDbContext.cs b/src/MongODM.Core/IDbContext.cs index 6f65c2ab..a54ad96d 100644 --- a/src/MongODM.Core/IDbContext.cs +++ b/src/MongODM.Core/IDbContext.cs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.ExecContext; using Etherna.MongoDB.Bson.Serialization; using Etherna.MongoDB.Driver; using Etherna.MongODM.Core.Domain.Models; @@ -120,6 +121,11 @@ public interface IDbContext /// ISerializerModifierAccessor SerializerModifierAccessor { get; } + /// + /// ExecutionContext handler. + /// + IExecutionContext ExecutionContext { get; } + // Methods. /// /// Save current model changes on db. diff --git a/src/MongODM.Core/IDbDependencies.cs b/src/MongODM.Core/IDbDependencies.cs index c9d1cce6..9f0bbb98 100644 --- a/src/MongODM.Core/IDbDependencies.cs +++ b/src/MongODM.Core/IDbDependencies.cs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.ExecContext; using Etherna.MongoDB.Bson.Serialization; using Etherna.MongODM.Core.ProxyModels; using Etherna.MongODM.Core.Repositories; @@ -28,6 +29,7 @@ public interface IDbDependencies IDbMaintainer DbMaintainer { get; } IDbMigrationManager DbMigrationManager { get; } IDiscriminatorRegistry DiscriminatorRegistry { get; } + IExecutionContext ExecutionContext { get; } IProxyGenerator ProxyGenerator { get; } IRepositoryRegistry RepositoryRegistry { get; } ISchemaRegistry SchemaRegistry { get; } diff --git a/src/MongODM.Core/Utility/DbContextExecutionContextHandler.cs b/src/MongODM.Core/Utility/DbContextExecutionContextHandler.cs new file mode 100644 index 00000000..99655a4b --- /dev/null +++ b/src/MongODM.Core/Utility/DbContextExecutionContextHandler.cs @@ -0,0 +1,62 @@ +using Etherna.ExecContext; +using Etherna.ExecContext.Exceptions; +using System; +using System.Collections; +using System.Collections.Generic; +using System.Linq; + +namespace Etherna.MongODM.Core.Utility +{ + internal class DbContextExecutionContextHandler : IDisposable + { + // Consts. + private const string HandlerKey = "DbContextExecutionContextHandler"; + + // Fields. + private readonly ICollection requestes; + + // Constructors and dispose. + public DbContextExecutionContextHandler( + IDbContext dbContext) + { + DbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); + + var executionContext = dbContext.ExecutionContext; + if (executionContext.Items is null) + throw new ExecutionContextNotFoundException(); + + if (!executionContext.Items.ContainsKey(HandlerKey)) + executionContext.Items.Add(HandlerKey, new List()); + + requestes = (ICollection)executionContext.Items[HandlerKey]!; + + lock (((ICollection)requestes).SyncRoot) + requestes.Add(this); + } + + public void Dispose() + { + lock (((ICollection)requestes).SyncRoot) + requestes.Remove(this); + } + + // Properties. + public IDbContext DbContext { get; } + + // Static methods. + public static IDbContext? GetCurrentDbContext(IExecutionContext executionContext) + { + if (executionContext.Items is null) + throw new ExecutionContextNotFoundException(); + + if (!executionContext.Items.ContainsKey(HandlerKey)) + return null; + + var requestes = (ICollection)executionContext.Items[HandlerKey]!; + + //get the last with a stack system, for recursing calls betweem different dbContexts + lock (((ICollection)requestes).SyncRoot) + return requestes.Reverse().FirstOrDefault()?.DbContext; + } + } +} From ed0ac38be9b13050f3a6aa6078feb4900062d0ba Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sat, 25 Dec 2021 23:57:28 +0100 Subject: [PATCH 44/78] Restricted unprotected access to collection and gridfs bucket --- ...calProxyTolerantDiscriminatorConvention.cs | 7 +- .../Migration/DocumentMigration.cs | 99 ++++---- .../Repositories/CollectionRepository.cs | 240 ++++++++++-------- .../Repositories/GridFSRepository.cs | 96 ++++--- .../Repositories/ICollectionRepository.cs | 4 +- .../Repositories/IGridFSRepository.cs | 5 +- .../Tasks/MigrateDbContextTask.cs | 4 +- .../DbContextExecutionContextHandler.cs | 2 +- 8 files changed, 253 insertions(+), 204 deletions(-) diff --git a/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs b/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs index 93da0071..66914dd7 100644 --- a/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs +++ b/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs @@ -18,6 +18,7 @@ using Etherna.MongoDB.Bson.Serialization; using Etherna.MongoDB.Bson.Serialization.Conventions; using Etherna.MongoDB.Bson.Serialization.Serializers; +using Etherna.MongODM.Core.Utility; using System; using System.Collections.Generic; using System.Linq; @@ -70,7 +71,11 @@ public IDbContext DbContext if (executionContext is null) throw new InvalidOperationException(); - return Core.DbContext.GetCurrentDbContext(executionContext); + var dbContext = DbContextExecutionContextHandler.TryGetCurrentDbContext(executionContext); + if (dbContext is null) + throw new InvalidOperationException(); + + return dbContext; } } public string ElementName { get; } diff --git a/src/MongODM.Core/Migration/DocumentMigration.cs b/src/MongODM.Core/Migration/DocumentMigration.cs index 713cd2bd..f343434b 100644 --- a/src/MongODM.Core/Migration/DocumentMigration.cs +++ b/src/MongODM.Core/Migration/DocumentMigration.cs @@ -24,7 +24,7 @@ namespace Etherna.MongODM.Core.Migration public abstract class DocumentMigration { // Properties. - public abstract ICollectionRepository SourceCollection { get; } + public abstract ICollectionRepository SourceRepository { get; } // Methods. /// @@ -45,73 +45,74 @@ public class DocumentMigration : DocumentMigration where TModel : class, IEntityModel { // Fields. - private readonly ICollectionRepository _sourceCollection; - private readonly Func destinationCollectionSelector; + private readonly ICollectionRepository _sourceRepository; + private readonly Func destinationRepositorySelector; private readonly Func modelConverter; // Constructors. - public DocumentMigration(ICollectionRepository collection) - : this(collection, collection, m => m) + public DocumentMigration(ICollectionRepository repository) + : this(repository, repository, m => m) { } public DocumentMigration( - ICollectionRepository sourceCollection, - ICollectionRepository destinationCollection, + ICollectionRepository sourceRepository, + ICollectionRepository destinationRepository, Func modelConverter) - : this(sourceCollection, _ => destinationCollection, modelConverter) + : this(sourceRepository, _ => destinationRepository, modelConverter) { } public DocumentMigration( - ICollectionRepository sourceCollection, - Func destinationCollectionSelector, + ICollectionRepository sourceRepository, + Func destinationRepositorySelector, Func modelConverter) { - _sourceCollection = sourceCollection ?? throw new ArgumentNullException(nameof(sourceCollection)); - this.destinationCollectionSelector = destinationCollectionSelector ?? throw new ArgumentNullException(nameof(destinationCollectionSelector)); + _sourceRepository = sourceRepository ?? throw new ArgumentNullException(nameof(sourceRepository)); + this.destinationRepositorySelector = destinationRepositorySelector ?? throw new ArgumentNullException(nameof(destinationRepositorySelector)); this.modelConverter = modelConverter ?? throw new ArgumentNullException(nameof(modelConverter)); } // Properties. - public override ICollectionRepository SourceCollection => _sourceCollection; + public override ICollectionRepository SourceRepository => _sourceRepository; // Methods. - public override async Task MigrateAsync( + public override Task MigrateAsync( int callbackEveryTotDocuments = 0, Func? callbackAsync = null, - CancellationToken cancellationToken = default) - { - if (callbackEveryTotDocuments < 0) - throw new ArgumentOutOfRangeException(nameof(callbackEveryTotDocuments), "Value can't be negative"); - - // Migrate documents. - var totMigratedDocuments = 0L; - await _sourceCollection.Collection.Find(FilterDefinition.Empty, new FindOptions { NoCursorTimeout = true }) - .ForEachAsync(async model => - { - var destinationCollection = destinationCollectionSelector(model); - - // Verify if needs to skip this model. - if (destinationCollection is null) - return; - - // Replace if it's the same collection, insert one otherwise. - if (SourceCollection == destinationCollection) - await destinationCollection.ReplaceAsync(model, updateDependentDocuments: false).ConfigureAwait(false); - else - await destinationCollection.CreateAsync(modelConverter(model)).ConfigureAwait(false); - - // Increment counter. - totMigratedDocuments++; - - // Execute callback. - if (callbackEveryTotDocuments > 0 && - totMigratedDocuments % callbackEveryTotDocuments == 0 && - callbackAsync != null) - await callbackAsync(totMigratedDocuments).ConfigureAwait(false); - - }, cancellationToken).ConfigureAwait(false); - - return MigrationResult.Succeeded(totMigratedDocuments); - } + CancellationToken cancellationToken = default) => + _sourceRepository.AccessToCollectionAsync(async sourceCollection => + { + if (callbackEveryTotDocuments < 0) + throw new ArgumentOutOfRangeException(nameof(callbackEveryTotDocuments), "Value can't be negative"); + + // Migrate documents. + var totMigratedDocuments = 0L; + await sourceCollection.Find(FilterDefinition.Empty, new FindOptions { NoCursorTimeout = true }) + .ForEachAsync(async model => + { + var destinationRepository = destinationRepositorySelector(model); + + // Verify if needs to skip this model. + if (destinationRepository is null) + return; + + // Replace if it's the same collection, insert one otherwise. + if (SourceRepository == destinationRepository) + await destinationRepository.ReplaceAsync(model, updateDependentDocuments: false).ConfigureAwait(false); + else + await destinationRepository.CreateAsync(modelConverter(model)).ConfigureAwait(false); + + // Increment counter. + totMigratedDocuments++; + + // Execute callback. + if (callbackEveryTotDocuments > 0 && + totMigratedDocuments % callbackEveryTotDocuments == 0 && + callbackAsync != null) + await callbackAsync(totMigratedDocuments).ConfigureAwait(false); + + }, cancellationToken).ConfigureAwait(false); + + return MigrationResult.Succeeded(totMigratedDocuments); + }); } } diff --git a/src/MongODM.Core/Repositories/CollectionRepository.cs b/src/MongODM.Core/Repositories/CollectionRepository.cs index 8af97b36..646fc72f 100644 --- a/src/MongODM.Core/Repositories/CollectionRepository.cs +++ b/src/MongODM.Core/Repositories/CollectionRepository.cs @@ -49,78 +49,93 @@ public CollectionRepository(CollectionRepositoryOptions options) } // Properties. - public IMongoCollection Collection => _collection ??= DbContext.Database.GetCollection(options.Name); public override string Name => options.Name; // Public methods. - public override async Task BuildIndexesAsync(ISchemaRegistry schemaRegistry, CancellationToken cancellationToken = default) + public Task AccessToCollectionAsync(Func, Task> action) => + AccessToCollectionAsync(async collection => + { + await action(collection).ConfigureAwait(false); + return 0; + }); + + public Task AccessToCollectionAsync(Func, Task> func) { - var newIndexes = new List<(string name, CreateIndexModel createIndex)>(); + if (_collection is null) + _collection = DbContext.Database.GetCollection(options.Name); + + throw new NotImplementedException(); + } - // Define new indexes. - //repository defined - newIndexes.AddRange(options.IndexBuilders.Select(pair => + public override Task BuildIndexesAsync(ISchemaRegistry schemaRegistry, CancellationToken cancellationToken = default) => + AccessToCollectionAsync(async collection => { - var (keys, options) = pair; - if (options.Name == null) + var newIndexes = new List<(string name, CreateIndexModel createIndex)>(); + + // Define new indexes. + //repository defined + newIndexes.AddRange(options.IndexBuilders.Select(pair => { - try - { - var renderedKeys = keys.Render(Collection.DocumentSerializer, Collection.Settings.SerializerRegistry); - options.Name = $"doc_{ string.Join("_", renderedKeys.Names) }"; - } - catch (InvalidOperationException) + var (keys, options) = pair; + if (options.Name == null) { - throw new MongodmIndexBuildingException($"Can't build custom index in collection \"{Name}\""); + try + { + var renderedKeys = keys.Render(collection.DocumentSerializer, collection.Settings.SerializerRegistry); + options.Name = $"doc_{ string.Join("_", renderedKeys.Names) }"; + } + catch (InvalidOperationException) + { + throw new MongodmIndexBuildingException($"Can't build custom index in collection \"{Name}\""); + } } - } - - return (options.Name, new CreateIndexModel(keys, options)); - })); - - //referenced documents - var dependencies = DbContext.SchemaRegistry.GetIdMemberDependenciesFromRootModel(typeof(TModel)); - var idPaths = dependencies - .Select(dependency => dependency.MemberPathToString()) - .Distinct(); - - newIndexes.AddRange(idPaths.Select(path => - ($"ref_{path}", - new CreateIndexModel( - Builders.IndexKeys.Ascending(path), - new CreateIndexOptions - { - Name = $"ref_{path}", - Sparse = true - })))); - - // Get current indexes. - var currentIndexes = new List(); - using (var indexList = await Collection.Indexes.ListAsync(cancellationToken).ConfigureAwait(false)) - while (await indexList.MoveNextAsync(cancellationToken).ConfigureAwait(false)) - currentIndexes.AddRange(indexList.Current); - - // Remove old indexes. - foreach (var oldIndex in from index in currentIndexes - let indexName = index.GetElement("name").Value.ToString() - where indexName != "_id_" - where !newIndexes.Any(newIndex => newIndex.name == indexName) - select index) - { - await Collection.Indexes.DropOneAsync(oldIndex.GetElement("name").Value.ToString(), cancellationToken).ConfigureAwait(false); - } + return (options.Name, new CreateIndexModel(keys, options)); + })); + + //referenced documents + var dependencies = DbContext.SchemaRegistry.GetIdMemberDependenciesFromRootModel(typeof(TModel)); + + var idPaths = dependencies + .Select(dependency => dependency.MemberPathToString()) + .Distinct(); + + newIndexes.AddRange(idPaths.Select(path => + ($"ref_{path}", + new CreateIndexModel( + Builders.IndexKeys.Ascending(path), + new CreateIndexOptions + { + Name = $"ref_{path}", + Sparse = true + })))); + + // Get current indexes. + var currentIndexes = new List(); + using (var indexList = await collection.Indexes.ListAsync(cancellationToken).ConfigureAwait(false)) + while (await indexList.MoveNextAsync(cancellationToken).ConfigureAwait(false)) + currentIndexes.AddRange(indexList.Current); + + // Remove old indexes. + foreach (var oldIndex in from index in currentIndexes + let indexName = index.GetElement("name").Value.ToString() + where indexName != "_id_" + where !newIndexes.Any(newIndex => newIndex.name == indexName) + select index) + { + await collection.Indexes.DropOneAsync(oldIndex.GetElement("name").Value.ToString(), cancellationToken).ConfigureAwait(false); + } - // Build new indexes. - if (newIndexes.Any()) - await Collection.Indexes.CreateManyAsync(newIndexes.Select(i => i.createIndex), cancellationToken).ConfigureAwait(false); - } + // Build new indexes. + if (newIndexes.Any()) + await collection.Indexes.CreateManyAsync(newIndexes.Select(i => i.createIndex), cancellationToken).ConfigureAwait(false); + }); public virtual Task> FindAsync( FilterDefinition filter, FindOptions? options = null, CancellationToken cancellationToken = default) => - Collection.FindAsync(filter, options, cancellationToken); + AccessToCollectionAsync(collection => collection.FindAsync(filter, options, cancellationToken)); public Task FindOneAsync( Expression> predicate, @@ -129,13 +144,14 @@ public Task FindOneAsync( public virtual Task QueryElementsAsync( Func, Task> query, - AggregateOptions? aggregateOptions = null) - { - if (query is null) - throw new ArgumentNullException(nameof(query)); + AggregateOptions? aggregateOptions = null) => + AccessToCollectionAsync(collection => + { + if (query is null) + throw new ArgumentNullException(nameof(query)); - return query(Collection.AsQueryable(aggregateOptions)); - } + return query(collection.AsQueryable(aggregateOptions)); + }); public async Task> QueryPaginatedElementsAsync( Func, IMongoQueryable> filter, @@ -201,20 +217,21 @@ public virtual Task ReplaceAsync( // Protected methods. protected override Task CreateOnDBAsync(IEnumerable models, CancellationToken cancellationToken) => - Collection.InsertManyAsync(models, null, cancellationToken); + AccessToCollectionAsync(collection => collection.InsertManyAsync(models, null, cancellationToken)); protected override Task CreateOnDBAsync(TModel model, CancellationToken cancellationToken) => - Collection.InsertOneAsync(model, null, cancellationToken); + AccessToCollectionAsync(collection => collection.InsertOneAsync(model, null, cancellationToken)); - protected override Task DeleteOnDBAsync(TModel model, CancellationToken cancellationToken) - { - if (model is null) - throw new ArgumentNullException(nameof(model)); + protected override Task DeleteOnDBAsync(TModel model, CancellationToken cancellationToken) => + AccessToCollectionAsync(collection => + { + if (model is null) + throw new ArgumentNullException(nameof(model)); - return Collection.DeleteOneAsync( - Builders.Filter.Eq(m => m.Id, model.Id), - cancellationToken); - } + return collection.DeleteOneAsync( + Builders.Filter.Eq(m => m.Id, model.Id), + cancellationToken); + }); protected override async Task FindOneOnDBAsync(TKey id, CancellationToken cancellationToken = default) { @@ -232,54 +249,57 @@ protected override async Task FindOneOnDBAsync(TKey id, CancellationToke } // Helpers. - private async Task FindOneOnDBAsync( + private Task FindOneOnDBAsync( Expression> predicate, - CancellationToken cancellationToken = default) - { - if (predicate is null) - throw new ArgumentNullException(nameof(predicate)); + CancellationToken cancellationToken = default) => + AccessToCollectionAsync(async collection => + { + if (predicate is null) + throw new ArgumentNullException(nameof(predicate)); - using var cursor = await Collection.FindAsync(predicate, cancellationToken: cancellationToken).ConfigureAwait(false); - var element = await cursor.FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false); + using var cursor = await collection.FindAsync(predicate, cancellationToken: cancellationToken).ConfigureAwait(false); + var element = await cursor.FirstOrDefaultAsync(cancellationToken).ConfigureAwait(false); - if (element == default(TModel)) - throw new MongodmEntityNotFoundException("Can't find element"); + if (element == default(TModel)) + throw new MongodmEntityNotFoundException("Can't find element"); - return element; - } + return element; + }); + - private async Task ReplaceHelperAsync( + private Task ReplaceHelperAsync( TModel model, IClientSessionHandle? session, bool updateDependentDocuments, - CancellationToken cancellationToken) - { - if (model == null) - throw new ArgumentNullException(nameof(model)); - - // Replace on db. - if (session == null) + CancellationToken cancellationToken) => + AccessToCollectionAsync(async collection => { - await Collection.ReplaceOneAsync( - Builders.Filter.Eq(m => m.Id, model.Id), - model, - cancellationToken: cancellationToken).ConfigureAwait(false); - } - else - { - await Collection.ReplaceOneAsync( - session, - Builders.Filter.Eq(m => m.Id, model.Id), - model, - cancellationToken: cancellationToken).ConfigureAwait(false); - } + if (model == null) + throw new ArgumentNullException(nameof(model)); + + // Replace on db. + if (session == null) + { + await collection.ReplaceOneAsync( + Builders.Filter.Eq(m => m.Id, model.Id), + model, + cancellationToken: cancellationToken).ConfigureAwait(false); + } + else + { + await collection.ReplaceOneAsync( + session, + Builders.Filter.Eq(m => m.Id, model.Id), + model, + cancellationToken: cancellationToken).ConfigureAwait(false); + } - // Update dependent documents. - if (updateDependentDocuments) - DbContext.DbMaintainer.OnUpdatedModel((IAuditable)model, model.Id); + // Update dependent documents. + if (updateDependentDocuments) + DbContext.DbMaintainer.OnUpdatedModel((IAuditable)model, model.Id); - // Reset changed members. - ((IAuditable)model).ResetChangedMembers(); - } + // Reset changed members. + ((IAuditable)model).ResetChangedMembers(); + }); } } \ No newline at end of file diff --git a/src/MongODM.Core/Repositories/GridFSRepository.cs b/src/MongODM.Core/Repositories/GridFSRepository.cs index d0c70700..3705602a 100644 --- a/src/MongODM.Core/Repositories/GridFSRepository.cs +++ b/src/MongODM.Core/Repositories/GridFSRepository.cs @@ -46,18 +46,32 @@ public GridFSRepository(GridFSRepositoryOptions options) } // Properties. - public IGridFSBucket GridFSBucket => - _gridFSBucket ??= new GridFSBucket(DbContext.Database, new GridFSBucketOptions { BucketName = options.Name }); public override string Name => options.Name; // Methods. + public Task AccessToGridFSBucketAsync(Func action) => + AccessToGridFSBucketAsync(async bucket => + { + await action(bucket).ConfigureAwait(false); + return 0; + }); + + public Task AccessToGridFSBucketAsync(Func> func) + { + if (_gridFSBucket is null) + _gridFSBucket = new GridFSBucket(DbContext.Database, new GridFSBucketOptions { BucketName = options.Name }); + + throw new NotImplementedException(); + } + public override Task BuildIndexesAsync(ISchemaRegistry schemaRegistry, CancellationToken cancellationToken = default) => Task.CompletedTask; public virtual Task DownloadAsBytesAsync(string id, CancellationToken cancellationToken = default) => - GridFSBucket.DownloadAsBytesAsync(ObjectId.Parse(id), null, cancellationToken); + AccessToGridFSBucketAsync(bucket => bucket.DownloadAsBytesAsync(ObjectId.Parse(id), null, cancellationToken)); public virtual async Task DownloadAsStreamAsync(string id, CancellationToken cancellationToken = default) => - await GridFSBucket.OpenDownloadStreamAsync(ObjectId.Parse(id), null, cancellationToken).ConfigureAwait(false); + await AccessToGridFSBucketAsync(bucket => + bucket.OpenDownloadStreamAsync(ObjectId.Parse(id), null, cancellationToken)).ConfigureAwait(false); // Protected methods. protected override async Task CreateOnDBAsync(IEnumerable models, CancellationToken cancellationToken) @@ -69,48 +83,52 @@ protected override async Task CreateOnDBAsync(IEnumerable models, Cancel await CreateOnDBAsync(model, cancellationToken).ConfigureAwait(false); } - protected override async Task CreateOnDBAsync(TModel model, CancellationToken cancellationToken) - { - if (model is null) - throw new ArgumentNullException(nameof(model)); - - // Upload. - model.Stream.Position = 0; - var id = await GridFSBucket.UploadFromStreamAsync(model.Name, model.Stream, new GridFSUploadOptions + protected override Task CreateOnDBAsync(TModel model, CancellationToken cancellationToken) => + AccessToGridFSBucketAsync(async bucket => { - Metadata = options.MetadataSerializer?.Invoke(model) - }, cancellationToken).ConfigureAwait(false); - ReflectionHelper.SetValue(model, m => m.Id, id.ToString()); - } + if (model is null) + throw new ArgumentNullException(nameof(model)); - protected override Task DeleteOnDBAsync(TModel model, CancellationToken cancellationToken) - { - if (model is null) - throw new ArgumentNullException(nameof(model)); + // Upload. + model.Stream.Position = 0; + var id = await bucket.UploadFromStreamAsync(model.Name, model.Stream, new GridFSUploadOptions + { + Metadata = options.MetadataSerializer?.Invoke(model) + }, cancellationToken).ConfigureAwait(false); + ReflectionHelper.SetValue(model, m => m.Id, id.ToString()); + }); - return GridFSBucket.DeleteAsync(ObjectId.Parse(model.Id), cancellationToken); - } - protected override async Task FindOneOnDBAsync(string id, CancellationToken cancellationToken = default) - { - if (id == null) - throw new ArgumentNullException(nameof(id)); + protected override Task DeleteOnDBAsync(TModel model, CancellationToken cancellationToken) => + AccessToGridFSBucketAsync(bucket => + { + if (model is null) + throw new ArgumentNullException(nameof(model)); - var filter = Builders.Filter.Eq("_id", ObjectId.Parse(id)); - var mongoFile = await(await GridFSBucket.FindAsync(filter, cancellationToken: cancellationToken).ConfigureAwait(false)) - .SingleOrDefaultAsync(cancellationToken).ConfigureAwait(false); - if (mongoFile == null) - throw new MongodmEntityNotFoundException($"Can't find key {id}"); + return bucket.DeleteAsync(ObjectId.Parse(model.Id), cancellationToken); + }); - var file = DbContext.ProxyGenerator.CreateInstance(DbContext); - ReflectionHelper.SetValue(file, m => m.Id, mongoFile.Id.ToString()); - ReflectionHelper.SetValue(file, m => m.Length, mongoFile.Length); - ReflectionHelper.SetValue(file, m => m.Name, mongoFile.Filename); + protected override Task FindOneOnDBAsync(string id, CancellationToken cancellationToken = default) => + AccessToGridFSBucketAsync(async bucket => + { + if (id == null) + throw new ArgumentNullException(nameof(id)); - // Deserialize metadata. - options.MetadataDeserializer?.Invoke(mongoFile.Metadata, file); + var filter = Builders.Filter.Eq("_id", ObjectId.Parse(id)); + var mongoFile = await (await bucket.FindAsync(filter, cancellationToken: cancellationToken).ConfigureAwait(false)) + .SingleOrDefaultAsync(cancellationToken).ConfigureAwait(false); + if (mongoFile == null) + throw new MongodmEntityNotFoundException($"Can't find key {id}"); - return file; - } + var file = DbContext.ProxyGenerator.CreateInstance(DbContext); + ReflectionHelper.SetValue(file, m => m.Id, mongoFile.Id.ToString()); + ReflectionHelper.SetValue(file, m => m.Length, mongoFile.Length); + ReflectionHelper.SetValue(file, m => m.Name, mongoFile.Filename); + + // Deserialize metadata. + options.MetadataDeserializer?.Invoke(mongoFile.Metadata, file); + + return file; + }); } } \ No newline at end of file diff --git a/src/MongODM.Core/Repositories/ICollectionRepository.cs b/src/MongODM.Core/Repositories/ICollectionRepository.cs index 7ee08b12..7b9d1e85 100644 --- a/src/MongODM.Core/Repositories/ICollectionRepository.cs +++ b/src/MongODM.Core/Repositories/ICollectionRepository.cs @@ -39,7 +39,9 @@ Task ReplaceAsync( public interface ICollectionRepository : IRepository, ICollectionRepository where TModel : class, IEntityModel { - IMongoCollection Collection { get; } + Task AccessToCollectionAsync(Func, Task> action); + + Task AccessToCollectionAsync(Func, Task> func); Task> FindAsync( FilterDefinition filter, diff --git a/src/MongODM.Core/Repositories/IGridFSRepository.cs b/src/MongODM.Core/Repositories/IGridFSRepository.cs index 454e1f10..c3d9b313 100644 --- a/src/MongODM.Core/Repositories/IGridFSRepository.cs +++ b/src/MongODM.Core/Repositories/IGridFSRepository.cs @@ -14,6 +14,7 @@ using Etherna.MongoDB.Driver.GridFS; using Etherna.MongODM.Core.Domain.Models; +using System; using System.IO; using System.Threading; using System.Threading.Tasks; @@ -22,7 +23,9 @@ namespace Etherna.MongODM.Core.Repositories { public interface IGridFSRepository : IRepository { - IGridFSBucket GridFSBucket { get; } + Task AccessToGridFSBucketAsync(Func action); + + Task AccessToGridFSBucketAsync(Func> func); Task DownloadAsBytesAsync(string id, CancellationToken cancellationToken = default); diff --git a/src/MongODM.Core/Tasks/MigrateDbContextTask.cs b/src/MongODM.Core/Tasks/MigrateDbContextTask.cs index 387ed69f..ce23121e 100644 --- a/src/MongODM.Core/Tasks/MigrateDbContextTask.cs +++ b/src/MongODM.Core/Tasks/MigrateDbContextTask.cs @@ -50,7 +50,7 @@ public async Task RunAsync(string dbMigrationOpId, string taskId) async procDocs => { dbMigrationOp.AddLog(new DocumentMigrationLog( - docMigration.SourceCollection.Name, + docMigration.SourceRepository.Name, MigrationLogBase.ExecutionState.Executing, procDocs)); @@ -59,7 +59,7 @@ public async Task RunAsync(string dbMigrationOpId, string taskId) //ended document migration log dbMigrationOp.AddLog(new DocumentMigrationLog( - docMigration.SourceCollection.Name, + docMigration.SourceRepository.Name, result.Succeded ? MigrationLogBase.ExecutionState.Succeded : MigrationLogBase.ExecutionState.Failed, diff --git a/src/MongODM.Core/Utility/DbContextExecutionContextHandler.cs b/src/MongODM.Core/Utility/DbContextExecutionContextHandler.cs index 99655a4b..c2ed3354 100644 --- a/src/MongODM.Core/Utility/DbContextExecutionContextHandler.cs +++ b/src/MongODM.Core/Utility/DbContextExecutionContextHandler.cs @@ -44,7 +44,7 @@ public void Dispose() public IDbContext DbContext { get; } // Static methods. - public static IDbContext? GetCurrentDbContext(IExecutionContext executionContext) + public static IDbContext? TryGetCurrentDbContext(IExecutionContext executionContext) { if (executionContext.Items is null) throw new ExecutionContextNotFoundException(); From 14a048c07bb6cd4ae1a695ed05c2cc4b33a0b464 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sun, 26 Dec 2021 00:13:28 +0100 Subject: [PATCH 45/78] Implemented accessor methods --- .../Repositories/CollectionRepository.cs | 13 +++++++++++-- src/MongODM.Core/Repositories/GridFSRepository.cs | 13 +++++++++++-- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/src/MongODM.Core/Repositories/CollectionRepository.cs b/src/MongODM.Core/Repositories/CollectionRepository.cs index 646fc72f..50824042 100644 --- a/src/MongODM.Core/Repositories/CollectionRepository.cs +++ b/src/MongODM.Core/Repositories/CollectionRepository.cs @@ -20,6 +20,7 @@ using Etherna.MongODM.Core.Extensions; using Etherna.MongODM.Core.ProxyModels; using Etherna.MongODM.Core.Serialization.Mapping; +using Etherna.MongODM.Core.Utility; using System; using System.Collections.Generic; using System.Linq; @@ -59,12 +60,20 @@ public Task AccessToCollectionAsync(Func, Task> action) return 0; }); - public Task AccessToCollectionAsync(Func, Task> func) + public async Task AccessToCollectionAsync(Func, Task> func) { + if (func is null) + throw new ArgumentNullException(nameof(func)); + + // Initialize collection cache. if (_collection is null) _collection = DbContext.Database.GetCollection(options.Name); - throw new NotImplementedException(); + // Execute func into execution context. + using (new DbContextExecutionContextHandler(DbContext)) + { + return await func(_collection).ConfigureAwait(false); + } } public override Task BuildIndexesAsync(ISchemaRegistry schemaRegistry, CancellationToken cancellationToken = default) => diff --git a/src/MongODM.Core/Repositories/GridFSRepository.cs b/src/MongODM.Core/Repositories/GridFSRepository.cs index 3705602a..6598af8f 100644 --- a/src/MongODM.Core/Repositories/GridFSRepository.cs +++ b/src/MongODM.Core/Repositories/GridFSRepository.cs @@ -18,6 +18,7 @@ using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Exceptions; using Etherna.MongODM.Core.Serialization.Mapping; +using Etherna.MongODM.Core.Utility; using System; using System.Collections.Generic; using System.IO; @@ -56,12 +57,20 @@ public Task AccessToGridFSBucketAsync(Func action) => return 0; }); - public Task AccessToGridFSBucketAsync(Func> func) + public async Task AccessToGridFSBucketAsync(Func> func) { + if (func is null) + throw new ArgumentNullException(nameof(func)); + + // Initialize bucket cache. if (_gridFSBucket is null) _gridFSBucket = new GridFSBucket(DbContext.Database, new GridFSBucketOptions { BucketName = options.Name }); - throw new NotImplementedException(); + // Execute func into execution context. + using (new DbContextExecutionContextHandler(DbContext)) + { + return await func(_gridFSBucket).ConfigureAwait(false); + } } public override Task BuildIndexesAsync(ISchemaRegistry schemaRegistry, CancellationToken cancellationToken = default) => Task.CompletedTask; From e91a4352a66112f4120cb83d14f81f010f1bf50f Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sun, 26 Dec 2021 16:50:27 +0100 Subject: [PATCH 46/78] registration order fix --- .../Extensions/ServiceCollectionExtensions.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/MongODM.AspNetCore/Extensions/ServiceCollectionExtensions.cs b/src/MongODM.AspNetCore/Extensions/ServiceCollectionExtensions.cs index cad5c257..cabd71c6 100644 --- a/src/MongODM.AspNetCore/Extensions/ServiceCollectionExtensions.cs +++ b/src/MongODM.AspNetCore/Extensions/ServiceCollectionExtensions.cs @@ -68,6 +68,12 @@ public static IMongODMConfiguration AddMongODM( taskRunnerBuilder.SetMongODMOptions(options); }); + services.AddExecutionContext(); + + services.TryAddSingleton(); + services.TryAddSingleton(); + services.TryAddSingleton(sp => (TTaskRunner)sp.GetRequiredService()); + /* Register discriminator convention on typeof(object) because we need a method to handle * default returned instance from static calls to BsonSerializer.LookupDiscriminatorConvention(Type). * Several points internal to drivers invoke this method, and we can't avoid it. We need to set the default. @@ -77,12 +83,6 @@ public static IMongODMConfiguration AddMongODM( BsonSerializer.RegisterDiscriminatorConvention(typeof(object), new HierarchicalProxyTolerantDiscriminatorConvention("_t", execContext)); - services.AddExecutionContext(); - - services.TryAddSingleton(); - services.TryAddSingleton(); - services.TryAddSingleton(sp => (TTaskRunner)sp.GetRequiredService()); - // DbContext internal. //dependencies /***** From f380c2d51b2b291cb8e30e9854c9a65b9d837cc9 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sun, 26 Dec 2021 17:39:59 +0100 Subject: [PATCH 47/78] Renamed DbExecutionContextHandler --- ...erarchicalProxyTolerantDiscriminatorConvention.cs | 2 +- .../Repositories/CollectionRepository.cs | 2 +- src/MongODM.Core/Repositories/GridFSRepository.cs | 2 +- ...ontextHandler.cs => DbExecutionContextHandler.cs} | 12 ++++++------ 4 files changed, 9 insertions(+), 9 deletions(-) rename src/MongODM.Core/Utility/{DbContextExecutionContextHandler.cs => DbExecutionContextHandler.cs} (78%) diff --git a/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs b/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs index 66914dd7..f4cfebc7 100644 --- a/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs +++ b/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs @@ -71,7 +71,7 @@ public IDbContext DbContext if (executionContext is null) throw new InvalidOperationException(); - var dbContext = DbContextExecutionContextHandler.TryGetCurrentDbContext(executionContext); + var dbContext = DbExecutionContextHandler.TryGetCurrentDbContext(executionContext); if (dbContext is null) throw new InvalidOperationException(); diff --git a/src/MongODM.Core/Repositories/CollectionRepository.cs b/src/MongODM.Core/Repositories/CollectionRepository.cs index 50824042..aab461a4 100644 --- a/src/MongODM.Core/Repositories/CollectionRepository.cs +++ b/src/MongODM.Core/Repositories/CollectionRepository.cs @@ -70,7 +70,7 @@ public async Task AccessToCollectionAsync(Func(options.Name); // Execute func into execution context. - using (new DbContextExecutionContextHandler(DbContext)) + using (new DbExecutionContextHandler(DbContext)) { return await func(_collection).ConfigureAwait(false); } diff --git a/src/MongODM.Core/Repositories/GridFSRepository.cs b/src/MongODM.Core/Repositories/GridFSRepository.cs index 6598af8f..f9ef8b3d 100644 --- a/src/MongODM.Core/Repositories/GridFSRepository.cs +++ b/src/MongODM.Core/Repositories/GridFSRepository.cs @@ -67,7 +67,7 @@ public async Task AccessToGridFSBucketAsync(Func requestes; + private readonly ICollection requestes; // Constructors and dispose. - public DbContextExecutionContextHandler( + public DbExecutionContextHandler( IDbContext dbContext) { DbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); @@ -26,9 +26,9 @@ public DbContextExecutionContextHandler( throw new ExecutionContextNotFoundException(); if (!executionContext.Items.ContainsKey(HandlerKey)) - executionContext.Items.Add(HandlerKey, new List()); + executionContext.Items.Add(HandlerKey, new List()); - requestes = (ICollection)executionContext.Items[HandlerKey]!; + requestes = (ICollection)executionContext.Items[HandlerKey]!; lock (((ICollection)requestes).SyncRoot) requestes.Add(this); @@ -52,7 +52,7 @@ public void Dispose() if (!executionContext.Items.ContainsKey(HandlerKey)) return null; - var requestes = (ICollection)executionContext.Items[HandlerKey]!; + var requestes = (ICollection)executionContext.Items[HandlerKey]!; //get the last with a stack system, for recursing calls betweem different dbContexts lock (((ICollection)requestes).SyncRoot) From ff81ec5d27014b6de79eaaaed7e9f7c617cc648a Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Wed, 29 Dec 2021 15:13:02 +0100 Subject: [PATCH 48/78] Implemented child dbcontexts --- src/MongODM.AspNetCore/MongODMConfiguration.cs | 6 +++++- src/MongODM.Core/DbContext.cs | 11 ++++++++++- src/MongODM.Core/IDbContextBuilder.cs | 6 +++++- src/MongODM.Core/Options/DbContextOptions.cs | 14 ++++++++++++++ 4 files changed, 34 insertions(+), 3 deletions(-) diff --git a/src/MongODM.AspNetCore/MongODMConfiguration.cs b/src/MongODM.AspNetCore/MongODMConfiguration.cs index 5b423f74..aa8374a7 100644 --- a/src/MongODM.AspNetCore/MongODMConfiguration.cs +++ b/src/MongODM.AspNetCore/MongODMConfiguration.cs @@ -17,6 +17,7 @@ using Microsoft.Extensions.DependencyInjection; using System; using System.Collections.Generic; +using System.Linq; using System.Threading; namespace Etherna.MongODM.AspNetCore @@ -114,7 +115,10 @@ public IMongODMConfiguration AddDbContext( var dbContext = dbContextCreator(sp); // Initialize instance. - dbContext.Initialize(dependencies, options); + dbContext.Initialize( + dependencies, + options, + options.ChildDbContextTypes.Select(dbContextType => (IDbContext)sp.GetRequiredService(dbContextType))); return dbContext; }); diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index 6844ec5d..1539e617 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -41,6 +41,7 @@ public abstract class DbContext : IDbContext, IDbContextBuilder // Fields. private bool? _isSeeded; private BsonSerializerRegistry _serializerRegistry = default!; + private IEnumerable childDbContexts = default!; private bool isInitialized; private readonly ReaderWriterLockSlim isSeededLock = new(); //support read/write locks private readonly SemaphoreSlim seedingSemaphore = new(1, 1); //support async/await @@ -49,7 +50,8 @@ public abstract class DbContext : IDbContext, IDbContextBuilder protected DbContext() { } public void Initialize( IDbDependencies dependencies, - IDbContextOptions options) + IDbContextOptions options, + IEnumerable childDbContexts) { if (isInitialized) throw new InvalidOperationException("DbContext already initialized"); @@ -59,6 +61,7 @@ public void Initialize( throw new ArgumentNullException(nameof(options)); // Set dependencies. + this.childDbContexts = childDbContexts; DbCache = dependencies.DbCache; DbMaintainer = dependencies.DbMaintainer; DbMigrationManager = dependencies.DbMigrationManager; @@ -241,6 +244,12 @@ public virtual async Task SaveChangesAsync(CancellationToken cancellationToken = } } } + + // Save changes on child dbcontexts. + foreach (var child in childDbContexts) + { + await child.SaveChangesAsync(cancellationToken).ConfigureAwait(false); + } } public async Task SeedIfNeededAsync() diff --git a/src/MongODM.Core/IDbContextBuilder.cs b/src/MongODM.Core/IDbContextBuilder.cs index 8bfd674a..47664916 100644 --- a/src/MongODM.Core/IDbContextBuilder.cs +++ b/src/MongODM.Core/IDbContextBuilder.cs @@ -1,9 +1,13 @@ using Etherna.MongODM.Core.Options; +using System.Collections.Generic; namespace Etherna.MongODM.Core { public interface IDbContextBuilder { - void Initialize(IDbDependencies dependencies, IDbContextOptions options); + void Initialize( + IDbDependencies dependencies, + IDbContextOptions options, + IEnumerable childDbContexts); } } diff --git a/src/MongODM.Core/Options/DbContextOptions.cs b/src/MongODM.Core/Options/DbContextOptions.cs index 2b591a6c..77eaf88d 100644 --- a/src/MongODM.Core/Options/DbContextOptions.cs +++ b/src/MongODM.Core/Options/DbContextOptions.cs @@ -12,12 +12,17 @@ // See the License for the specific language governing permissions and // limitations under the License. +using System; +using System.Collections.Generic; using System.Linq; namespace Etherna.MongODM.Core.Options { public class DbContextOptions : IDbContextOptions { + // Fields. + private readonly List _childDbContextTypes = new(); + // Properties. public string ConnectionString { get; set; } = "mongodb://localhost/localDb"; public string DbName => ConnectionString.Split('?')[0] @@ -26,5 +31,14 @@ public class DbContextOptions : IDbContextOptions public DocumentSemVerOptions DocumentSemVer { get; set; } = new DocumentSemVerOptions(); public string? Identifier { get; set; } public ModelMapVersionOptions ModelMapVersion { get; set; } = new ModelMapVersionOptions(); + public IEnumerable ChildDbContextTypes => _childDbContextTypes; + + // Methods. + public void ParentFor() where + TDbContext : class, IDbContext + { + if (!_childDbContextTypes.Contains(typeof(TDbContext))) + _childDbContextTypes.Add(typeof(TDbContext)); + } } } From 82c38117b3e60cc1b4025a9c83ac37ee3ac25c4d Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Wed, 29 Dec 2021 16:35:36 +0100 Subject: [PATCH 49/78] Implemented dbcontext segregation in DbCache --- src/MongODM.Core/DbContext.cs | 1 + src/MongODM.Core/Utility/DbCache.cs | 25 +++++++++++++++++++++---- src/MongODM.Core/Utility/IDbCache.cs | 2 +- 3 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index 1539e617..9c273b90 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -89,6 +89,7 @@ public void Initialize( }); // Initialize internal dependencies. + DbCache.Initialize(this); DbMaintainer.Initialize(this); DbMigrationManager.Initialize(this); DiscriminatorRegistry.Initialize(this); diff --git a/src/MongODM.Core/Utility/DbCache.cs b/src/MongODM.Core/Utility/DbCache.cs index 7a420b9e..fe28b5cf 100644 --- a/src/MongODM.Core/Utility/DbCache.cs +++ b/src/MongODM.Core/Utility/DbCache.cs @@ -16,15 +16,17 @@ using Etherna.MongODM.Core.Domain.Models; using System; using System.Collections.Generic; +using System.Text; namespace Etherna.MongODM.Core.Utility { public class DbCache : IDbCache { // Consts. - private const string CacheKey = "DBCache"; + private const string CacheKeyPrefix = "DBCache-"; // Fields. + private string cacheKey = default!; private readonly IExecutionContext executionContext; // Constructors. @@ -33,7 +35,22 @@ public DbCache(IExecutionContext executionContext) this.executionContext = executionContext ?? throw new ArgumentNullException(nameof(executionContext)); } + public void Initialize(IDbContext dbContext) + { + if (dbContext is null) + throw new ArgumentNullException(nameof(dbContext)); + if (IsInitialized) + throw new InvalidOperationException("Instance already initialized"); + + var cacheKeyBuilder = new StringBuilder(CacheKeyPrefix); + cacheKeyBuilder.Append(dbContext.Identifier); + cacheKey = cacheKeyBuilder.ToString(); + + IsInitialized = true; + } + // Properties. + public bool IsInitialized { get; private set; } public IReadOnlyDictionary LoadedModels { get @@ -85,10 +102,10 @@ private Dictionary GetScopedCache() if (executionContext.Items is null) throw new InvalidOperationException("Execution context can't have null Items here"); - if (!executionContext.Items.ContainsKey(CacheKey)) - executionContext.Items.Add(CacheKey, new Dictionary()); + if (!executionContext.Items.ContainsKey(cacheKey)) + executionContext.Items.Add(cacheKey, new Dictionary()); - return (Dictionary)executionContext.Items[CacheKey]!; + return (Dictionary)executionContext.Items[cacheKey]!; } } } diff --git a/src/MongODM.Core/Utility/IDbCache.cs b/src/MongODM.Core/Utility/IDbCache.cs index 651bf971..2685d930 100644 --- a/src/MongODM.Core/Utility/IDbCache.cs +++ b/src/MongODM.Core/Utility/IDbCache.cs @@ -20,7 +20,7 @@ namespace Etherna.MongODM.Core.Utility /// /// Interface for implementation. /// - public interface IDbCache + public interface IDbCache : IDbContextInitializable { // Properties. /// From e912d807077821b52a35ef00ef721d583060a353 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Tue, 18 Jan 2022 19:12:38 +0100 Subject: [PATCH 50/78] Updated hangfire --- src/MongODM.Hangfire/MongODM.Hangfire.csproj | 2 +- src/MongODM/MongODM.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MongODM.Hangfire/MongODM.Hangfire.csproj b/src/MongODM.Hangfire/MongODM.Hangfire.csproj index 514b681f..199262ed 100644 --- a/src/MongODM.Hangfire/MongODM.Hangfire.csproj +++ b/src/MongODM.Hangfire/MongODM.Hangfire.csproj @@ -26,7 +26,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index a27b3ed6..1fb461e1 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -30,7 +30,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 81baf43fe4c6e14d5fee481640a1d7f0f9334de7 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Tue, 18 Jan 2022 20:18:40 +0100 Subject: [PATCH 51/78] implemented modm-112 --- .../Repositories/CollectionRepository.cs | 15 ++++++++++++--- .../Repositories/ICollectionRepository.cs | 1 + 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/MongODM.Core/Repositories/CollectionRepository.cs b/src/MongODM.Core/Repositories/CollectionRepository.cs index aab461a4..7af3fb77 100644 --- a/src/MongODM.Core/Repositories/CollectionRepository.cs +++ b/src/MongODM.Core/Repositories/CollectionRepository.cs @@ -167,11 +167,20 @@ public async Task> QueryPaginatedElementsAsync> orderKeySelector, int page, int take, + bool useDescendingOrder = false, CancellationToken cancellationToken = default) { - var elements = await QueryElementsAsync(elements => filter(elements) - .Paginate(orderKeySelector, page, take) - .ToListAsync(cancellationToken)).ConfigureAwait(false); + var elements = await QueryElementsAsync(elements => + + useDescendingOrder ? + + filter(elements) + .PaginateDescending(orderKeySelector, page, take) + .ToListAsync(cancellationToken) : + + filter(elements) + .Paginate(orderKeySelector, page, take) + .ToListAsync(cancellationToken)).ConfigureAwait(false); var maxPage = (await QueryElementsAsync(elements => filter(elements) .CountAsync(cancellationToken)).ConfigureAwait(false) - 1) / take; diff --git a/src/MongODM.Core/Repositories/ICollectionRepository.cs b/src/MongODM.Core/Repositories/ICollectionRepository.cs index 7b9d1e85..6e786767 100644 --- a/src/MongODM.Core/Repositories/ICollectionRepository.cs +++ b/src/MongODM.Core/Repositories/ICollectionRepository.cs @@ -61,6 +61,7 @@ Task> QueryPaginatedElementsAsync> orderKeySelector, int page, int take, + bool useDescendingOrder = false, CancellationToken cancellationToken = default); Task ReplaceAsync( From 7f323a1ccbbccfa7feb66a394bc3cc364df35563 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Mon, 7 Feb 2022 20:09:42 +0100 Subject: [PATCH 52/78] DbExecutionContextHandler create exec context if necessary --- src/MongODM.AspNetCore/MongODM.AspNetCore.csproj | 2 +- src/MongODM.Core/MongODM.Core.csproj | 2 +- .../Utility/DbExecutionContextHandler.cs | 12 +++++++++--- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj index 338293cb..f90f7e39 100644 --- a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj +++ b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj @@ -30,7 +30,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index 17a648e8..f79bc743 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -25,7 +25,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.Core/Utility/DbExecutionContextHandler.cs b/src/MongODM.Core/Utility/DbExecutionContextHandler.cs index 19a0cdc6..18589a6b 100644 --- a/src/MongODM.Core/Utility/DbExecutionContextHandler.cs +++ b/src/MongODM.Core/Utility/DbExecutionContextHandler.cs @@ -1,4 +1,5 @@ using Etherna.ExecContext; +using Etherna.ExecContext.AsyncLocal; using Etherna.ExecContext.Exceptions; using System; using System.Collections; @@ -13,6 +14,7 @@ internal class DbExecutionContextHandler : IDisposable private const string HandlerKey = "DbContextExecutionContextHandler"; // Fields. + private readonly IAsyncLocalContextHandler? asyncLocalContextHandler; private readonly ICollection requestes; // Constructors and dispose. @@ -22,10 +24,11 @@ public DbExecutionContextHandler( DbContext = dbContext ?? throw new ArgumentNullException(nameof(dbContext)); var executionContext = dbContext.ExecutionContext; - if (executionContext.Items is null) - throw new ExecutionContextNotFoundException(); - if (!executionContext.Items.ContainsKey(HandlerKey)) + if (executionContext.Items is null) //if an execution context doesn't exist, create it + asyncLocalContextHandler = AsyncLocalContext.Instance.InitAsyncLocalContext(); + + if (!executionContext.Items!.ContainsKey(HandlerKey)) executionContext.Items.Add(HandlerKey, new List()); requestes = (ICollection)executionContext.Items[HandlerKey]!; @@ -38,6 +41,9 @@ public void Dispose() { lock (((ICollection)requestes).SyncRoot) requestes.Remove(this); + + if (asyncLocalContextHandler is not null) + asyncLocalContextHandler.Dispose(); } // Properties. From 664e4174a260342619741ac7ffd7e43dd1e62849 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Thu, 10 Mar 2022 00:10:16 +0100 Subject: [PATCH 53/78] update dependencies --- src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj | 2 +- src/MongODM.AspNetCore/MongODM.AspNetCore.csproj | 2 +- src/MongODM.Core/Domain/Models/EntityModelBase.cs | 2 +- src/MongODM.Core/MongODM.Core.csproj | 2 +- .../Serialization/Serializers/ModelMapSerializer.cs | 2 +- src/MongODM.Hangfire/MongODM.Hangfire.csproj | 2 +- src/MongODM/MongODM.csproj | 2 +- test/MongODM.Core.Tests/MongODM.Core.Tests.csproj | 4 ++-- 8 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj index acd5996b..4ffbdcab 100644 --- a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj +++ b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj @@ -32,7 +32,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj index f90f7e39..a1677a11 100644 --- a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj +++ b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj @@ -31,7 +31,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.Core/Domain/Models/EntityModelBase.cs b/src/MongODM.Core/Domain/Models/EntityModelBase.cs index dac468ab..28769fef 100644 --- a/src/MongODM.Core/Domain/Models/EntityModelBase.cs +++ b/src/MongODM.Core/Domain/Models/EntityModelBase.cs @@ -44,7 +44,7 @@ public override bool Equals(object? obj) if (ReferenceEquals(this, obj)) return true; if (obj is null) return false; if (EqualityComparer.Default.Equals(Id, default!) || - !(obj is IEntityModel) || + obj is not IEntityModel || EqualityComparer.Default.Equals((obj as IEntityModel)!.Id, default!)) return false; return GetType() == obj.GetType() && EqualityComparer.Default.Equals(Id, (obj as IEntityModel)!.Id); diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index f79bc743..9fcbe9b9 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -26,7 +26,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs index 65991cb9..21fe8714 100644 --- a/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs @@ -188,7 +188,7 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati var bsonDocument = new BsonDocument(); using var bsonWriter = new ExtendedBsonDocumentWriter(bsonDocument) { - IsRootDocument = !(context.Writer is ExtendedBsonDocumentWriter) + IsRootDocument = context.Writer is not ExtendedBsonDocumentWriter }; var localContext = BsonSerializationContext.CreateRoot( bsonWriter, diff --git a/src/MongODM.Hangfire/MongODM.Hangfire.csproj b/src/MongODM.Hangfire/MongODM.Hangfire.csproj index 199262ed..1407945c 100644 --- a/src/MongODM.Hangfire/MongODM.Hangfire.csproj +++ b/src/MongODM.Hangfire/MongODM.Hangfire.csproj @@ -22,7 +22,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index 1fb461e1..05f9fe08 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -26,7 +26,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj index 8e27e176..df8f95ce 100644 --- a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj +++ b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj @@ -9,8 +9,8 @@ - - + + all From 269ac824f5bb57219b8c86eaa74c77b37f554924 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Thu, 10 Mar 2022 00:11:58 +0100 Subject: [PATCH 54/78] update mongodb drivers --- src/MongODM.Core/MongODM.Core.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index 9fcbe9b9..8711c54f 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -23,8 +23,8 @@ - - + + all From 9f54b1819e0f2e11088f88dc8acd4defa47d99bf Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Fri, 1 Apr 2022 17:07:41 +0200 Subject: [PATCH 55/78] Add generation of XML files Description fixes --- .editorconfig | 3 +++ src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj | 1 + src/MongODM.AspNetCore/MongODM.AspNetCore.csproj | 1 + .../HierarchicalProxyTolerantDiscriminatorConvention.cs | 1 + src/MongODM.Core/Migration/DocumentMigration.cs | 1 + src/MongODM.Core/MongODM.Core.csproj | 1 + src/MongODM.Core/ReflectionHelper.cs | 1 - src/MongODM.Core/Serialization/Mapping/ISchemaRegistry.cs | 1 - src/MongODM.Hangfire/MongODM.Hangfire.csproj | 1 + src/MongODM/MongODM.csproj | 1 + 10 files changed, 10 insertions(+), 2 deletions(-) diff --git a/.editorconfig b/.editorconfig index 1b9ef798..436132e9 100644 --- a/.editorconfig +++ b/.editorconfig @@ -24,3 +24,6 @@ dotnet_diagnostic.CA1040.severity = none # Sometime they are needed # CA1812: Avoid uninstantiated internal classes dotnet_diagnostic.CA1812.severity = none # Doing extensive use of dependency injection + +# CS1591: Missing XML comment for publicly visible type or member +dotnet_diagnostic.CS1591.severity = none # There are currently too much missing descriptions diff --git a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj index 4ffbdcab..5511f8dd 100644 --- a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj +++ b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj @@ -21,6 +21,7 @@ LICENSE true true + True diff --git a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj index a1677a11..ea0577e0 100644 --- a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj +++ b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj @@ -19,6 +19,7 @@ LICENSE true true + True diff --git a/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs b/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs index f4cfebc7..bceb8320 100644 --- a/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs +++ b/src/MongODM.Core/Conventions/HierarchicalProxyTolerantDiscriminatorConvention.cs @@ -48,6 +48,7 @@ public HierarchicalProxyTolerantDiscriminatorConvention( /// Remove when static call will be removed. /// /// Discriminator element name + /// Execution context public HierarchicalProxyTolerantDiscriminatorConvention( string elementName, IExecutionContext executionContext) diff --git a/src/MongODM.Core/Migration/DocumentMigration.cs b/src/MongODM.Core/Migration/DocumentMigration.cs index f343434b..b13ba900 100644 --- a/src/MongODM.Core/Migration/DocumentMigration.cs +++ b/src/MongODM.Core/Migration/DocumentMigration.cs @@ -32,6 +32,7 @@ public abstract class DocumentMigration /// /// Interval of processed documents between callback invokations. 0 if ignore callback /// The async callback function. Parameter is number of processed documents + /// /// The migration result public abstract Task MigrateAsync(int callbackEveryTotDocuments = 0, Func? callbackAsync = null, CancellationToken cancellationToken = default); } diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index 8711c54f..4a250228 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -19,6 +19,7 @@ LICENSE true true + True diff --git a/src/MongODM.Core/ReflectionHelper.cs b/src/MongODM.Core/ReflectionHelper.cs index 393fdb4b..88154684 100644 --- a/src/MongODM.Core/ReflectionHelper.cs +++ b/src/MongODM.Core/ReflectionHelper.cs @@ -169,7 +169,6 @@ public static TMember GetValueFromLambda(TModel source, Express /// /// Return the list of writable instance property of a type /// - /// The model type /// The list of properties public static IEnumerable GetWritableInstanceProperties(Type objectType) { diff --git a/src/MongODM.Core/Serialization/Mapping/ISchemaRegistry.cs b/src/MongODM.Core/Serialization/Mapping/ISchemaRegistry.cs index b1a2c4de..9ab1ace3 100644 --- a/src/MongODM.Core/Serialization/Mapping/ISchemaRegistry.cs +++ b/src/MongODM.Core/Serialization/Mapping/ISchemaRegistry.cs @@ -71,7 +71,6 @@ IModelMapsSchemaBuilder AddModelMapsSchema( /// /// Get active class map from schemas, or create a default classMap for model type /// - /// The model type /// The active model map BsonClassMap GetActiveClassMap(Type modelType); diff --git a/src/MongODM.Hangfire/MongODM.Hangfire.csproj b/src/MongODM.Hangfire/MongODM.Hangfire.csproj index 1407945c..ae7a6404 100644 --- a/src/MongODM.Hangfire/MongODM.Hangfire.csproj +++ b/src/MongODM.Hangfire/MongODM.Hangfire.csproj @@ -19,6 +19,7 @@ LICENSE true true + True diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index 05f9fe08..2ddd2d26 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -19,6 +19,7 @@ LICENSE true true + True From 4750f18d43dc0269850d3bfff91ce929adf30224 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Fri, 1 Apr 2022 17:30:47 +0200 Subject: [PATCH 56/78] add support to .net 6 --- .github/workflows/myget-unstable-deploy.yml | 14 ++++++-------- .github/workflows/nuget-stable-deploy.yml | 14 ++++++-------- .../MongODM.AspNetCore.UI.csproj | 7 +++---- .../ServiceCollectionExtensions.cs | 15 +++++++-------- src/MongODM.AspNetCore/MongODM.AspNetCore.csproj | 6 +++--- src/MongODM.Core/MongODM.Core.csproj | 4 ++-- .../Serialization/Mapping/SchemaRegistry.cs | 2 -- .../Serializers/ReferenceSerializer.cs | 2 -- src/MongODM.Hangfire/MongODM.Hangfire.csproj | 6 +++--- src/MongODM/MongODM.csproj | 6 +++--- test/MongODM.Core.Tests/MongODM.Core.Tests.csproj | 2 +- 11 files changed, 34 insertions(+), 44 deletions(-) diff --git a/.github/workflows/myget-unstable-deploy.yml b/.github/workflows/myget-unstable-deploy.yml index 69780800..907453f4 100644 --- a/.github/workflows/myget-unstable-deploy.yml +++ b/.github/workflows/myget-unstable-deploy.yml @@ -15,15 +15,13 @@ jobs: with: fetch-depth: 0 - - name: Setup .NET Core SDK 3.1.x - uses: actions/setup-dotnet@v1 + - name: Setup dotnet + uses: actions/setup-dotnet@v2 with: - dotnet-version: '3.1.x' - - - name: Setup .NET SDK 5.0.x - uses: actions/setup-dotnet@v1 - with: - dotnet-version: '5.0.x' + dotnet-version: | + 3.1.x + 5.0.x + 6.0.x - name: Build with dotnet run: dotnet build --configuration Release diff --git a/.github/workflows/nuget-stable-deploy.yml b/.github/workflows/nuget-stable-deploy.yml index 6d298437..ebe21826 100644 --- a/.github/workflows/nuget-stable-deploy.yml +++ b/.github/workflows/nuget-stable-deploy.yml @@ -14,15 +14,13 @@ jobs: with: fetch-depth: 0 - - name: Setup .NET Core SDK 3.1.x - uses: actions/setup-dotnet@v1 + - name: Setup dotnet + uses: actions/setup-dotnet@v2 with: - dotnet-version: '3.1.x' - - - name: Setup .NET SDK 5.0.x - uses: actions/setup-dotnet@v1 - with: - dotnet-version: '5.0.x' + dotnet-version: | + 3.1.x + 5.0.x + 6.0.x - name: Build with dotnet run: dotnet build --configuration Release diff --git a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj index 5511f8dd..aa60df38 100644 --- a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj +++ b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj @@ -1,8 +1,7 @@  - netcoreapp3.1 - + netcoreapp3.1;net5.0;net6.0 true true Etherna.MongODM.AspNetCore.UI @@ -33,11 +32,11 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.AspNetCore.UI/ServiceCollectionExtensions.cs b/src/MongODM.AspNetCore.UI/ServiceCollectionExtensions.cs index 82548a1b..74545bfe 100644 --- a/src/MongODM.AspNetCore.UI/ServiceCollectionExtensions.cs +++ b/src/MongODM.AspNetCore.UI/ServiceCollectionExtensions.cs @@ -44,15 +44,14 @@ public static IServiceCollection AddMongODMAdminDashboard( routeModel => { foreach (var selector in routeModel.Selectors) - { - var attributeRouteModel = selector.AttributeRouteModel; + if (selector.AttributeRouteModel?.Template is not null) + { + var segments = selector.AttributeRouteModel.Template.Split('/'); + if (segments[0] == AreaName) + segments[0] = dashboardOptions.BasePath; - var segments = selector.AttributeRouteModel.Template.Split('/'); - if (segments[0] == AreaName) - segments[0] = dashboardOptions.BasePath; - - selector.AttributeRouteModel.Template = string.Join("/", segments); - } + selector.AttributeRouteModel.Template = string.Join("/", segments); + } }); }); diff --git a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj index ea0577e0..ca416f2a 100644 --- a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj +++ b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1;net5.0 + netcoreapp3.1;net5.0;net6.0 true Etherna.MongODM.AspNetCore Etherna Sagl @@ -32,11 +32,11 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index 4a250228..4ba168ff 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -27,11 +27,11 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.Core/Serialization/Mapping/SchemaRegistry.cs b/src/MongODM.Core/Serialization/Mapping/SchemaRegistry.cs index add0a610..bf584066 100644 --- a/src/MongODM.Core/Serialization/Mapping/SchemaRegistry.cs +++ b/src/MongODM.Core/Serialization/Mapping/SchemaRegistry.cs @@ -331,9 +331,7 @@ private void CompileDependencyRegisters( //model maps schema serializers if (memberSerializer is IModelMapsContainerSerializer schemaSerializer) { -#pragma warning disable CA1508 // Avoid dead conditional code. Here code analyzer is wrong bool? useCascadeDelete = (memberSerializer as IReferenceContainerSerializer)?.UseCascadeDelete; -#pragma warning restore CA1508 // Avoid dead conditional code foreach (var childClassMap in schemaSerializer.AllChildClassMaps) CompileDependencyRegisters(modelMap, childClassMap, lastEntityClassMap, currentMemberPath, useCascadeDelete); } diff --git a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs index cd587069..53466474 100644 --- a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs @@ -153,10 +153,8 @@ public override TModelBase Deserialize(BsonDeserializationContext context, BsonD if (model != null) { var id = model.Id; -#pragma warning disable CA1508 // Avoid dead conditional code if (id == null) //ignore refered instances without id return null!; -#pragma warning restore CA1508 // Avoid dead conditional code // Check if model as been loaded in cache. if (dbContext.DbCache.LoadedModels.ContainsKey(id) && diff --git a/src/MongODM.Hangfire/MongODM.Hangfire.csproj b/src/MongODM.Hangfire/MongODM.Hangfire.csproj index ae7a6404..e2c65d7e 100644 --- a/src/MongODM.Hangfire/MongODM.Hangfire.csproj +++ b/src/MongODM.Hangfire/MongODM.Hangfire.csproj @@ -23,12 +23,12 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - - + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index 2ddd2d26..b1e8630d 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1;net5.0 + netcoreapp3.1;net5.0;net6.0 true Etherna.MongODM Etherna Sagl @@ -27,12 +27,12 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj index df8f95ce..76122349 100644 --- a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj +++ b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj @@ -1,7 +1,7 @@  - net5.0 + net6.0 true Etherna.MongODM.Core false From 3db71d4e4e7864d36af8d7de170756e54354d8fd Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sat, 2 Apr 2022 18:20:58 +0200 Subject: [PATCH 57/78] Add lambda for fix deserialized model in ModelMapSerializer Fix secondary serializer selection --- .../Domain/ModelMaps/OperationBaseMap.cs | 2 +- .../ModelMapDeserializationContext.cs | 18 ++++++++++++++++++ .../Serializers/ModelMapSerializer.cs | 19 ++++++++++++++++++- 3 files changed, 37 insertions(+), 2 deletions(-) create mode 100644 src/MongODM.Core/Serialization/Serializers/ModelMapDeserializationContext.cs diff --git a/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs b/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs index ff7d2fdb..e75017f1 100644 --- a/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs +++ b/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs @@ -26,7 +26,7 @@ public void Register(IDbContext dbContext) dbContext.SchemaRegistry.AddModelMapsSchema("ee726d4f-6e6a-44b0-bf3e-45322534c36d", customSerializer: new ModelMapSerializer( dbContext, - new DocumentSemVerOptions + overrideDocumentSemVerOptions: new DocumentSemVerOptions { CurrentVersion = dbContext.LibraryVersion, WriteInDocuments = false diff --git a/src/MongODM.Core/Serialization/Serializers/ModelMapDeserializationContext.cs b/src/MongODM.Core/Serialization/Serializers/ModelMapDeserializationContext.cs new file mode 100644 index 00000000..25d0bdca --- /dev/null +++ b/src/MongODM.Core/Serialization/Serializers/ModelMapDeserializationContext.cs @@ -0,0 +1,18 @@ +namespace Etherna.MongODM.Core.Serialization.Serializers +{ + public class ModelMapDeserializationContext + { + // Constructor. + public ModelMapDeserializationContext( + string? modelMapId, + SemanticVersion? semVer) + { + ModelMapId = modelMapId; + SemVer = semVer; + } + + // Properties. + public string? ModelMapId { get; } + public SemanticVersion? SemVer { get; } + } +} diff --git a/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs index 21fe8714..da8b6455 100644 --- a/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs @@ -23,6 +23,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; namespace Etherna.MongODM.Core.Serialization.Serializers { @@ -35,11 +36,13 @@ public class ModelMapSerializer : private readonly BsonElement documentSemVerElement; private readonly IDbContext dbContext; private readonly DocumentSemVerOptions documentSemVerOptions; + private readonly Func> fixDeserializedModelAsync; private readonly ModelMapVersionOptions modelMapVersionOptions; // Constructor. public ModelMapSerializer( IDbContext dbContext, + Func>? fixDeserializedModelAsync = null, DocumentSemVerOptions? overrideDocumentSemVerOptions = null, ModelMapVersionOptions? overrideModelMapVersionOptions = null) { @@ -48,6 +51,8 @@ public ModelMapSerializer( this.dbContext = dbContext; + this.fixDeserializedModelAsync = fixDeserializedModelAsync ?? ((m, _) => Task.FromResult(m)); + documentSemVerOptions = overrideDocumentSemVerOptions ?? dbContext.Options.DocumentSemVer; modelMapVersionOptions = overrideModelMapVersionOptions ?? dbContext.Options.ModelMapVersion; @@ -125,7 +130,14 @@ public override TModel Deserialize(BsonDeserializationContext context, BsonDeser //if a correct model map is identified with its id if (modelMapId != null && actualTypeSchema.AllMapsDictionary.ContainsKey(modelMapId)) { - var serializer = actualTypeSchema.AllMapsDictionary[modelMapId].BsonClassMapSerializer; + var modelMap = actualTypeSchema.AllMapsDictionary[modelMapId]; + + /* If is mapped a different serializer than the current one, choose it. + * Otherwise, if doesn't exist or is already the current, deserialize with BsonClassMap + */ + var serializer = modelMap.Serializer is not null && modelMap.Serializer != this ? + modelMap.Serializer : + modelMap.BsonClassMapSerializer; model = (TModel)serializer.Deserialize(localContext, args); } @@ -159,6 +171,11 @@ public override TModel Deserialize(BsonDeserializationContext context, BsonDeser } } + // Fix model. + var task = fixDeserializedModelAsync(model, new ModelMapDeserializationContext(modelMapId, documentSemVer)); + task.Wait(); + model = task.Result; + // Enable auditing. (model as IAuditable)?.EnableAuditing(); From 2e1340a50001ddbb0fe17056a30eb2aea2081e23 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Thu, 7 Apr 2022 01:29:36 +0200 Subject: [PATCH 58/78] minor refactor --- .../Serialization/Mapping/DiscriminatorRegistry.cs | 1 - src/MongODM.Core/Utility/DbCache.cs | 8 ++------ 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegistry.cs b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegistry.cs index 218d572a..c0c4114e 100644 --- a/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegistry.cs +++ b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegistry.cs @@ -28,7 +28,6 @@ public void Initialize(IDbContext dbContext) IsInitialized = true; } - // Properties. public bool IsInitialized { get; private set; } diff --git a/src/MongODM.Core/Utility/DbCache.cs b/src/MongODM.Core/Utility/DbCache.cs index fe28b5cf..fa466b15 100644 --- a/src/MongODM.Core/Utility/DbCache.cs +++ b/src/MongODM.Core/Utility/DbCache.cs @@ -27,14 +27,9 @@ public class DbCache : IDbCache // Fields. private string cacheKey = default!; - private readonly IExecutionContext executionContext; + private IExecutionContext executionContext = default!; // Constructors. - public DbCache(IExecutionContext executionContext) - { - this.executionContext = executionContext ?? throw new ArgumentNullException(nameof(executionContext)); - } - public void Initialize(IDbContext dbContext) { if (dbContext is null) @@ -45,6 +40,7 @@ public void Initialize(IDbContext dbContext) var cacheKeyBuilder = new StringBuilder(CacheKeyPrefix); cacheKeyBuilder.Append(dbContext.Identifier); cacheKey = cacheKeyBuilder.ToString(); + executionContext = dbContext.ExecutionContext; IsInitialized = true; } From 9b62de02e710d373160862f67836c5b50f6ca4c3 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Fri, 8 Apr 2022 01:39:50 +0200 Subject: [PATCH 59/78] Inject MongoClient with dbcontext init --- src/MongODM.AspNetCore/MongODMConfiguration.cs | 2 ++ src/MongODM.Core/DbContext.cs | 3 ++- src/MongODM.Core/IDbContextBuilder.cs | 4 +++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/MongODM.AspNetCore/MongODMConfiguration.cs b/src/MongODM.AspNetCore/MongODMConfiguration.cs index aa8374a7..8abfd072 100644 --- a/src/MongODM.AspNetCore/MongODMConfiguration.cs +++ b/src/MongODM.AspNetCore/MongODMConfiguration.cs @@ -12,6 +12,7 @@ // See the License for the specific language governing permissions and // limitations under the License. +using Etherna.MongoDB.Driver; using Etherna.MongODM.Core; using Etherna.MongODM.Core.Options; using Microsoft.Extensions.DependencyInjection; @@ -117,6 +118,7 @@ public IMongODMConfiguration AddDbContext( // Initialize instance. dbContext.Initialize( dependencies, + new MongoClient(options.ConnectionString), options, options.ChildDbContextTypes.Select(dbContextType => (IDbContext)sp.GetRequiredService(dbContextType))); diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index 9c273b90..fac6a5ba 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -50,6 +50,7 @@ public abstract class DbContext : IDbContext, IDbContextBuilder protected DbContext() { } public void Initialize( IDbDependencies dependencies, + IMongoClient mongoClient, IDbContextOptions options, IEnumerable childDbContexts) { @@ -82,7 +83,7 @@ public void Initialize( _serializerRegistry = (BsonSerializerRegistry)dependencies.BsonSerializerRegistry; // Initialize MongoDB driver. - Client = new MongoClient(options.ConnectionString); + Client = mongoClient; Database = Client.GetDatabase(options.DbName, new MongoDatabaseSettings { SerializerRegistry = _serializerRegistry diff --git a/src/MongODM.Core/IDbContextBuilder.cs b/src/MongODM.Core/IDbContextBuilder.cs index 47664916..fef5fb24 100644 --- a/src/MongODM.Core/IDbContextBuilder.cs +++ b/src/MongODM.Core/IDbContextBuilder.cs @@ -1,4 +1,5 @@ -using Etherna.MongODM.Core.Options; +using Etherna.MongoDB.Driver; +using Etherna.MongODM.Core.Options; using System.Collections.Generic; namespace Etherna.MongODM.Core @@ -7,6 +8,7 @@ public interface IDbContextBuilder { void Initialize( IDbDependencies dependencies, + IMongoClient mongoClient, IDbContextOptions options, IEnumerable childDbContexts); } From 4ba983add45017373a1b439aed8c58d8f65e9053 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Fri, 8 Apr 2022 02:56:17 +0200 Subject: [PATCH 60/78] init mongodb database as last operation in dbcontext initialization --- src/MongODM.Core/DbContext.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index fac6a5ba..d9837c11 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -82,13 +82,6 @@ public void Initialize( SerializerModifierAccessor = dependencies.SerializerModifierAccessor; _serializerRegistry = (BsonSerializerRegistry)dependencies.BsonSerializerRegistry; - // Initialize MongoDB driver. - Client = mongoClient; - Database = Client.GetDatabase(options.DbName, new MongoDatabaseSettings - { - SerializerRegistry = _serializerRegistry - }); - // Initialize internal dependencies. DbCache.Initialize(this); DbMaintainer.Initialize(this); @@ -116,6 +109,13 @@ public void Initialize( // Build and freeze schema registry. SchemaRegistry.Freeze(); + // Initialize MongoDB database. + Client = mongoClient; + Database = Client.GetDatabase(options.DbName, new MongoDatabaseSettings + { + SerializerRegistry = _serializerRegistry + }); + // Set as initialized. isInitialized = true; } From a84907c1f33d4ac2218537a851b4fedd699325d1 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Fri, 8 Apr 2022 18:33:37 +0200 Subject: [PATCH 61/78] minor name refactor --- src/MongODM.Core/DbContext.cs | 6 ++-- .../ProxyModels/ReferenceableInterceptor.cs | 4 +-- .../Repositories/IRepositoryRegistry.cs | 6 ++-- .../Repositories/RepositoryBase.cs | 2 +- .../Repositories/RepositoryRegistry.cs | 34 +++++++++---------- .../Tasks/MigrateDbContextTask.cs | 2 +- .../Tasks/UpdateDocDependenciesTask.cs | 4 +-- src/MongODM.Core/Utility/DbMaintainer.cs | 2 +- .../ReferenceableInterceptorTest.cs | 2 +- 9 files changed, 31 insertions(+), 31 deletions(-) diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index d9837c11..31b34678 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -92,7 +92,7 @@ public void Initialize( InitializeSerializerRegistry(); // Initialize repositories. - foreach (var repository in RepositoryRegistry.ModelRepositoryMap.Values) + foreach (var repository in RepositoryRegistry.RepositoriesByModelType.Values) repository.Initialize(this); // Register model maps. @@ -234,9 +234,9 @@ public virtual async Task SaveChangesAsync(CancellationToken cancellationToken = var modelType = ProxyGenerator.PurgeProxyType(model.GetType()); while (modelType != typeof(object)) //try to find right collection. Can't replace model if it is stored on gridfs { - if (RepositoryRegistry.ModelCollectionRepositoryMap.ContainsKey(modelType)) + if (RepositoryRegistry.CollectionRepositoriesByModelType.ContainsKey(modelType)) { - var repository = RepositoryRegistry.ModelCollectionRepositoryMap[modelType]; + var repository = RepositoryRegistry.CollectionRepositoriesByModelType[modelType]; await repository.ReplaceAsync(model, cancellationToken: cancellationToken).ConfigureAwait(false); break; } diff --git a/src/MongODM.Core/ProxyModels/ReferenceableInterceptor.cs b/src/MongODM.Core/ProxyModels/ReferenceableInterceptor.cs index 49638564..0712a319 100644 --- a/src/MongODM.Core/ProxyModels/ReferenceableInterceptor.cs +++ b/src/MongODM.Core/ProxyModels/ReferenceableInterceptor.cs @@ -42,14 +42,14 @@ public ReferenceableInterceptor( throw new ArgumentNullException(nameof(dbContext)); var repositoryModelType = typeof(TModel); - while (!dbContext.RepositoryRegistry.ModelRepositoryMap.ContainsKey(repositoryModelType)) + while (!dbContext.RepositoryRegistry.RepositoriesByModelType.ContainsKey(repositoryModelType)) { if (repositoryModelType == typeof(object)) throw new InvalidOperationException($"Cant find valid repository for model type {typeof(TModel)}"); repositoryModelType = repositoryModelType.BaseType; } - repository = dbContext.RepositoryRegistry.ModelRepositoryMap[repositoryModelType]; + repository = dbContext.RepositoryRegistry.RepositoriesByModelType[repositoryModelType]; } // Protected methods. diff --git a/src/MongODM.Core/Repositories/IRepositoryRegistry.cs b/src/MongODM.Core/Repositories/IRepositoryRegistry.cs index e070d0be..3fb93031 100644 --- a/src/MongODM.Core/Repositories/IRepositoryRegistry.cs +++ b/src/MongODM.Core/Repositories/IRepositoryRegistry.cs @@ -22,16 +22,16 @@ public interface IRepositoryRegistry : IDbContextInitializable /// /// Model-Repository map for collection types. /// - IReadOnlyDictionary ModelCollectionRepositoryMap { get; } + IReadOnlyDictionary CollectionRepositoriesByModelType { get; } /// /// Model-Repository map for gridfs types. /// - IReadOnlyDictionary ModelGridFSRepositoryMap { get; } + IReadOnlyDictionary GridFSRepositoriesByModelType { get; } /// /// Model-Repository map for both collection and gridfs types. /// - IReadOnlyDictionary ModelRepositoryMap { get; } + IReadOnlyDictionary RepositoriesByModelType { get; } } } \ No newline at end of file diff --git a/src/MongODM.Core/Repositories/RepositoryBase.cs b/src/MongODM.Core/Repositories/RepositoryBase.cs index 8fcd83c9..102a3a7f 100644 --- a/src/MongODM.Core/Repositories/RepositoryBase.cs +++ b/src/MongODM.Core/Repositories/RepositoryBase.cs @@ -169,7 +169,7 @@ private async Task CascadeDeleteMembersAsync(object currentModel, IEnumerable _modelCollectionRepositoryMap = default!; - private IReadOnlyDictionary _modelGridFSRepositoryMap = default!; - private IReadOnlyDictionary _modelRepositoryMap = default!; + private IReadOnlyDictionary _collectionRepositoriesByModelType = default!; + private IReadOnlyDictionary _gridFSRepositoriesByModelType = default!; + private IReadOnlyDictionary _repositoriesByModelType = default!; // Initializer. public void Initialize(IDbContext dbContext) @@ -40,11 +40,11 @@ public void Initialize(IDbContext dbContext) // Properties. public bool IsInitialized { get; private set; } - public IReadOnlyDictionary ModelCollectionRepositoryMap + public IReadOnlyDictionary CollectionRepositoriesByModelType { get { - if (_modelCollectionRepositoryMap is null) + if (_collectionRepositoriesByModelType is null) { var dbContextType = dbContext.GetType(); @@ -68,19 +68,19 @@ public IReadOnlyDictionary ModelCollectionRepositor }); // Initialize registry. - _modelCollectionRepositoryMap = repos.ToDictionary( + _collectionRepositoriesByModelType = repos.ToDictionary( prop => ((ICollectionRepository)prop.GetValue(dbContext)).GetModelType, prop => (ICollectionRepository)prop.GetValue(dbContext)); } - return _modelCollectionRepositoryMap; + return _collectionRepositoriesByModelType; } } - public IReadOnlyDictionary ModelGridFSRepositoryMap + public IReadOnlyDictionary GridFSRepositoriesByModelType { get { - if (_modelGridFSRepositoryMap is null) + if (_gridFSRepositoriesByModelType is null) { var dbContextType = dbContext.GetType(); @@ -104,32 +104,32 @@ public IReadOnlyDictionary ModelGridFSRepositoryMap }); //construct registry - _modelGridFSRepositoryMap = repos.ToDictionary( + _gridFSRepositoriesByModelType = repos.ToDictionary( prop => ((IGridFSRepository)prop.GetValue(dbContext)).GetModelType, prop => (IGridFSRepository)prop.GetValue(dbContext)); } - return _modelGridFSRepositoryMap; + return _gridFSRepositoriesByModelType; } } - public IReadOnlyDictionary ModelRepositoryMap + public IReadOnlyDictionary RepositoriesByModelType { get { - if (_modelRepositoryMap is null) + if (_repositoriesByModelType is null) { var repoMap = new Dictionary(); - foreach (var pair in ModelCollectionRepositoryMap) + foreach (var pair in CollectionRepositoriesByModelType) repoMap.Add(pair.Key, pair.Value); - foreach (var pair in ModelGridFSRepositoryMap) + foreach (var pair in GridFSRepositoriesByModelType) repoMap.Add(pair.Key, pair.Value); - _modelRepositoryMap = repoMap; + _repositoriesByModelType = repoMap; } - return _modelRepositoryMap; + return _repositoriesByModelType; } } } diff --git a/src/MongODM.Core/Tasks/MigrateDbContextTask.cs b/src/MongODM.Core/Tasks/MigrateDbContextTask.cs index ce23121e..41cdd693 100644 --- a/src/MongODM.Core/Tasks/MigrateDbContextTask.cs +++ b/src/MongODM.Core/Tasks/MigrateDbContextTask.cs @@ -69,7 +69,7 @@ public async Task RunAsync(string dbMigrationOpId, string taskId) } // Build indexes. - foreach (var repository in dbContext.RepositoryRegistry.ModelCollectionRepositoryMap.Values) + foreach (var repository in dbContext.RepositoryRegistry.CollectionRepositoriesByModelType.Values) { dbMigrationOp.AddLog(new IndexMigrationLog( repository.Name, diff --git a/src/MongODM.Core/Tasks/UpdateDocDependenciesTask.cs b/src/MongODM.Core/Tasks/UpdateDocDependenciesTask.cs index 9eb20a01..da415c87 100644 --- a/src/MongODM.Core/Tasks/UpdateDocDependenciesTask.cs +++ b/src/MongODM.Core/Tasks/UpdateDocDependenciesTask.cs @@ -51,10 +51,10 @@ public async Task RunAsync( // Get repository. /* Ignore document update if doesn't exists a collection that can handle its type. */ - if (!dbContext.RepositoryRegistry.ModelCollectionRepositoryMap.ContainsKey(typeof(TModel))) + if (!dbContext.RepositoryRegistry.CollectionRepositoriesByModelType.ContainsKey(typeof(TModel))) return; - var repository = (ICollectionRepository)dbContext.RepositoryRegistry.ModelCollectionRepositoryMap[typeof(TModel)]; + var repository = (ICollectionRepository)dbContext.RepositoryRegistry.CollectionRepositoriesByModelType[typeof(TModel)]; // Update models. HashSet upgradedDocumentsId = new(); diff --git a/src/MongODM.Core/Utility/DbMaintainer.cs b/src/MongODM.Core/Utility/DbMaintainer.cs index 0a1ef447..148e8392 100644 --- a/src/MongODM.Core/Utility/DbMaintainer.cs +++ b/src/MongODM.Core/Utility/DbMaintainer.cs @@ -60,7 +60,7 @@ public void OnUpdatedModel(IAuditable updatedModel, TKey modelId) // Group by root model type, and select only model types related to a collections. foreach (var dependencyGroup in referenceMemberMaps.GroupBy(memberMap => memberMap.RootModelMap.ModelType) - .Where(group => dbContext.RepositoryRegistry.ModelCollectionRepositoryMap.ContainsKey(group.Key))) + .Where(group => dbContext.RepositoryRegistry.CollectionRepositoriesByModelType.ContainsKey(group.Key))) { // Extract only id paths to referenced entities. var idPaths = dependencyGroup diff --git a/test/MongODM.Core.Tests/ReferenceableInterceptorTest.cs b/test/MongODM.Core.Tests/ReferenceableInterceptorTest.cs index 169b09a9..d0983800 100644 --- a/test/MongODM.Core.Tests/ReferenceableInterceptorTest.cs +++ b/test/MongODM.Core.Tests/ReferenceableInterceptorTest.cs @@ -39,7 +39,7 @@ public ReferenceableInterceptorTest() repositoryMock = new Mock>(); dbContextMock = new Mock(); - dbContextMock.Setup(c => c.RepositoryRegistry.ModelRepositoryMap) + dbContextMock.Setup(c => c.RepositoryRegistry.RepositoriesByModelType) .Returns(() => new Dictionary { [typeof(FakeModel)] = repositoryMock.Object From 8054145a6b77be9ae769d0af0f852f80f1694127 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sun, 10 Apr 2022 23:46:35 +0200 Subject: [PATCH 62/78] add a fallback model map --- .../Mapping/Schemas/IModelMapsSchema.cs | 1 + .../Schemas/IModelMapsSchemaBuilder.cs | 23 ++++++++++++-- .../IReferenceModelMapsSchemaBuilder.cs | 26 +++++++++++++--- .../Mapping/Schemas/ModelMapsSchema.cs | 17 ++++++++++ .../Mapping/Schemas/ModelMapsSchemaBase.cs | 14 ++++++++- .../Schemas/ReferenceModelMapsSchema.cs | 19 ++++++++++-- .../Serializers/ModelMapSerializer.cs | 31 +++++++++++++------ 7 files changed, 112 insertions(+), 19 deletions(-) diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchema.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchema.cs index f7211484..695d631e 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchema.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchema.cs @@ -24,6 +24,7 @@ public interface IModelMapsSchema : ISchema IModelMap ActiveMap { get; } IReadOnlyDictionary AllMapsDictionary { get; } IDbContext DbContext { get; } + IModelMap? FallbackModelMap { get; } IBsonSerializer? FallbackSerializer { get; } IEnumerable SecondaryMaps { get; } } diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchemaBuilder.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchemaBuilder.cs index 11edbced..2d02677b 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchemaBuilder.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchemaBuilder.cs @@ -18,17 +18,36 @@ namespace Etherna.MongODM.Core.Serialization.Mapping.Schemas { public interface IModelMapsSchemaBuilder - where TModel : class { // Methods. /// - /// Add a fallback serializer invoked in case of undefined schema id + /// Add a fallback serializer invoked in case of unrecognized schema id /// /// Fallback serializer /// This same model schema IModelMapsSchemaBuilder AddFallbackCustomSerializer( IBsonSerializer fallbackSerializer); + /// + /// Add a fallback model map invoked in case of unrecognized schema id, and absence of fallback serializer + /// + /// The model map inizializer + /// Id of the base model map for this model map + /// Custom serializer + /// This same model schema configuration + IModelMapsSchemaBuilder AddFallbackModelMap( + Action>? modelMapInitializer = null, + string? baseModelMapId = null, + IBsonSerializer? customSerializer = null); + + /// + /// Add a fallback model map invoked in case of unrecognized schema id, and absence of fallback serializer + /// + /// The model map + /// This same model schema configuration + IModelMapsSchemaBuilder AddFallbackModelMap( + ModelMap modelMap); + /// /// Register a secondary model map /// diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/IReferenceModelMapsSchemaBuilder.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/IReferenceModelMapsSchemaBuilder.cs index ec234056..36d82ee4 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/IReferenceModelMapsSchemaBuilder.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/IReferenceModelMapsSchemaBuilder.cs @@ -21,24 +21,42 @@ public interface IReferenceModelMapsSchemaBuilder { // Methods. /// - /// Add a fallback serializer invoked in case of undefined schema id + /// Add a fallback serializer invoked in case of unrecognized schema id /// /// Fallback serializer /// This same model schema IReferenceModelMapsSchemaBuilder AddFallbackCustomSerializer( IBsonSerializer fallbackSerializer); + /// + /// Add a fallback model map invoked in case of unrecognized schema id, and absence of fallback serializer + /// + /// The model map inizializer + /// Id of the base model map for this model map + /// This same model schema configuration + IReferenceModelMapsSchemaBuilder AddFallbackModelMap( + Action>? modelMapInitializer = null, + string? baseModelMapId = null); + + /// + /// Add a fallback model map invoked in case of unrecognized schema id, and absence of fallback serializer + /// + /// The model map + /// This same model schema configuration + IReferenceModelMapsSchemaBuilder AddFallbackModelMap( + ModelMap modelMap); + /// /// Register a secondary model map /// /// The map Id - /// Id of the base model map for this model map /// The model map inizializer + /// Id of the base model map for this model map /// This same model schema configuration IReferenceModelMapsSchemaBuilder AddSecondaryMap( string id, - string? baseModelMapId = null, - Action>? modelMapInitializer = null); + Action>? modelMapInitializer = null, + string? baseModelMapId = null); /// /// Register a secondary model map diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchema.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchema.cs index 2dcb7591..4cb07010 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchema.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchema.cs @@ -35,6 +35,23 @@ public IModelMapsSchemaBuilder AddFallbackCustomSerializer(IBsonSerializ return this; } + [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The new model map instance can't be disposed")] + public IModelMapsSchemaBuilder AddFallbackModelMap( + Action>? modelMapInitializer = null, + string? baseModelMapId = null, + IBsonSerializer? customSerializer = null) => + AddFallbackModelMap(new ModelMap( + "fallback", + new BsonClassMap(modelMapInitializer ?? (cm => cm.AutoMap())), + baseModelMapId, + customSerializer)); + + public IModelMapsSchemaBuilder AddFallbackModelMap(ModelMap modelMap) + { + AddFallbackModelMapHelper(modelMap); + return this; + } + [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The new model map instance can't be disposed")] public IModelMapsSchemaBuilder AddSecondaryMap( string id, diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchemaBase.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchemaBase.cs index d80381c6..2a560d54 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchemaBase.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchemaBase.cs @@ -69,6 +69,7 @@ public IReadOnlyDictionary AllMapsDictionary } } public IDbContext DbContext { get; } + public IModelMap? FallbackModelMap { get; protected set; } public IBsonSerializer? FallbackSerializer { get; protected set; } public override Type? ProxyModelType { get; } public IEnumerable SecondaryMaps => _secondaryMaps; @@ -79,12 +80,23 @@ protected void AddFallbackCustomSerializerHelper(IBsonSerializer fallbackSeriali { if (fallbackSerializer is null) throw new ArgumentNullException(nameof(fallbackSerializer)); - if (FallbackSerializer != null) + if (FallbackSerializer is not null) throw new InvalidOperationException("Fallback serializer already setted"); FallbackSerializer = fallbackSerializer; }); + protected void AddFallbackModelMapHelper(IModelMap fallbackModelMap) => + ExecuteConfigAction(() => + { + if (fallbackModelMap is null) + throw new ArgumentNullException(nameof(fallbackModelMap)); + if (FallbackModelMap is not null) + throw new InvalidOperationException("Fallback model map already setted"); + + FallbackModelMap = fallbackModelMap; + }); + protected void AddSecondaryMapHelper(IModelMap modelMap) => ExecuteConfigAction(() => { diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/ReferenceModelMapsSchema.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/ReferenceModelMapsSchema.cs index 7dc1ce50..1a76c537 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/ReferenceModelMapsSchema.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/ReferenceModelMapsSchema.cs @@ -34,11 +34,26 @@ public IReferenceModelMapsSchemaBuilder AddFallbackCustomSerializer(IBso return this; } + [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The new model map instance can't be disposed")] + public IReferenceModelMapsSchemaBuilder AddFallbackModelMap( + Action>? modelMapInitializer = null, + string? baseModelMapId = null) => + AddFallbackModelMap(new ModelMap( + "fallback", + new BsonClassMap(modelMapInitializer ?? (cm => cm.AutoMap())), + baseModelMapId)); + + public IReferenceModelMapsSchemaBuilder AddFallbackModelMap(ModelMap modelMap) + { + AddFallbackModelMapHelper(modelMap); + return this; + } + [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The new model map instance can't be disposed")] public IReferenceModelMapsSchemaBuilder AddSecondaryMap( string id, - string? baseModelMapId = null, - Action>? modelMapInitializer = null) => + Action>? modelMapInitializer = null, + string? baseModelMapId = null) => AddSecondaryMap(new ModelMap( id, new BsonClassMap(modelMapInitializer ?? (cm => cm.AutoMap())), diff --git a/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs index da8b6455..26e476a4 100644 --- a/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs @@ -20,6 +20,7 @@ using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Options; using Etherna.MongODM.Core.ProxyModels; +using Etherna.MongODM.Core.Serialization.Mapping; using System; using System.Collections.Generic; using System.Linq; @@ -130,15 +131,7 @@ public override TModel Deserialize(BsonDeserializationContext context, BsonDeser //if a correct model map is identified with its id if (modelMapId != null && actualTypeSchema.AllMapsDictionary.ContainsKey(modelMapId)) { - var modelMap = actualTypeSchema.AllMapsDictionary[modelMapId]; - - /* If is mapped a different serializer than the current one, choose it. - * Otherwise, if doesn't exist or is already the current, deserialize with BsonClassMap - */ - var serializer = modelMap.Serializer is not null && modelMap.Serializer != this ? - modelMap.Serializer : - modelMap.BsonClassMapSerializer; - model = (TModel)serializer.Deserialize(localContext, args); + model = DeserializeModelMapHelper(actualTypeSchema.AllMapsDictionary[modelMapId], localContext, args); } //else, if a fallback serializator exists @@ -147,10 +140,16 @@ public override TModel Deserialize(BsonDeserializationContext context, BsonDeser model = (TModel)actualTypeSchema.FallbackSerializer.Deserialize(localContext, args); } + //else, if a fallback model map exists + else if (actualTypeSchema.FallbackModelMap != null) + { + model = DeserializeModelMapHelper(actualTypeSchema.FallbackModelMap, localContext, args); + } + //else, deserialize wih current active model map else { - model = (TModel)actualTypeSchema.ActiveMap.BsonClassMapSerializer.Deserialize(localContext, args); + model = DeserializeModelMapHelper(actualTypeSchema.ActiveMap, localContext, args); } // Add model to cache. @@ -268,5 +267,17 @@ public bool TryGetMemberSerializationInfo(string memberName, out BsonSerializati bsonArray.Count >= 4 ? bsonArray[3].AsString : null), _ => throw new NotSupportedException(), }; + + private static TModel DeserializeModelMapHelper(IModelMap modelMap, BsonDeserializationContext context, BsonDeserializationArgs args) + { + /* If is mapped a different serializer than the current one, choose it. + * Otherwise, if doesn't exist or is already the current, deserialize with BsonClassMap + */ + var serializer = modelMap.Serializer is not null && modelMap.Serializer.GetType() != typeof(ModelMapSerializer) ? + modelMap.Serializer : + modelMap.BsonClassMapSerializer; + + return (TModel)serializer.Deserialize(context, args); + } } } From 1ca4d514d318898c8fdcb6aa2c75eaa0af872daa Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Sun, 10 Apr 2022 23:50:34 +0200 Subject: [PATCH 63/78] refactor on method arguments --- src/MongODM.Core/Repositories/CollectionRepository.cs | 3 +-- src/MongODM.Core/Repositories/GridFSRepository.cs | 3 +-- src/MongODM.Core/Repositories/IRepository.cs | 2 -- src/MongODM.Core/Repositories/RepositoryBase.cs | 2 +- src/MongODM.Core/Tasks/MigrateDbContextTask.cs | 2 +- 5 files changed, 4 insertions(+), 8 deletions(-) diff --git a/src/MongODM.Core/Repositories/CollectionRepository.cs b/src/MongODM.Core/Repositories/CollectionRepository.cs index 7af3fb77..b5361a6c 100644 --- a/src/MongODM.Core/Repositories/CollectionRepository.cs +++ b/src/MongODM.Core/Repositories/CollectionRepository.cs @@ -19,7 +19,6 @@ using Etherna.MongODM.Core.Exceptions; using Etherna.MongODM.Core.Extensions; using Etherna.MongODM.Core.ProxyModels; -using Etherna.MongODM.Core.Serialization.Mapping; using Etherna.MongODM.Core.Utility; using System; using System.Collections.Generic; @@ -76,7 +75,7 @@ public async Task AccessToCollectionAsync(Func + public override Task BuildIndexesAsync(CancellationToken cancellationToken = default) => AccessToCollectionAsync(async collection => { var newIndexes = new List<(string name, CreateIndexModel createIndex)>(); diff --git a/src/MongODM.Core/Repositories/GridFSRepository.cs b/src/MongODM.Core/Repositories/GridFSRepository.cs index f9ef8b3d..1c2f84b8 100644 --- a/src/MongODM.Core/Repositories/GridFSRepository.cs +++ b/src/MongODM.Core/Repositories/GridFSRepository.cs @@ -17,7 +17,6 @@ using Etherna.MongoDB.Driver.GridFS; using Etherna.MongODM.Core.Domain.Models; using Etherna.MongODM.Core.Exceptions; -using Etherna.MongODM.Core.Serialization.Mapping; using Etherna.MongODM.Core.Utility; using System; using System.Collections.Generic; @@ -73,7 +72,7 @@ public async Task AccessToGridFSBucketAsync(Func Task.CompletedTask; + public override Task BuildIndexesAsync(CancellationToken cancellationToken = default) => Task.CompletedTask; public virtual Task DownloadAsBytesAsync(string id, CancellationToken cancellationToken = default) => AccessToGridFSBucketAsync(bucket => bucket.DownloadAsBytesAsync(ObjectId.Parse(id), null, cancellationToken)); diff --git a/src/MongODM.Core/Repositories/IRepository.cs b/src/MongODM.Core/Repositories/IRepository.cs index d6370bd7..f773ad52 100644 --- a/src/MongODM.Core/Repositories/IRepository.cs +++ b/src/MongODM.Core/Repositories/IRepository.cs @@ -13,7 +13,6 @@ // limitations under the License. using Etherna.MongODM.Core.Domain.Models; -using Etherna.MongODM.Core.Serialization.Mapping; using System; using System.Collections.Generic; using System.Threading; @@ -29,7 +28,6 @@ public interface IRepository : IDbContextInitializable string Name { get; } Task BuildIndexesAsync( - ISchemaRegistry schemaRegistry, CancellationToken cancellationToken = default); Task CreateAsync( diff --git a/src/MongODM.Core/Repositories/RepositoryBase.cs b/src/MongODM.Core/Repositories/RepositoryBase.cs index 102a3a7f..33ac9f2a 100644 --- a/src/MongODM.Core/Repositories/RepositoryBase.cs +++ b/src/MongODM.Core/Repositories/RepositoryBase.cs @@ -49,7 +49,7 @@ public virtual void Initialize(IDbContext dbContext) public abstract string Name { get; } // Methods. - public abstract Task BuildIndexesAsync(ISchemaRegistry schemaRegistry, CancellationToken cancellationToken = default); + public abstract Task BuildIndexesAsync(CancellationToken cancellationToken = default); public Task CreateAsync(object model, CancellationToken cancellationToken = default) => CreateAsync((TModel)model, cancellationToken); diff --git a/src/MongODM.Core/Tasks/MigrateDbContextTask.cs b/src/MongODM.Core/Tasks/MigrateDbContextTask.cs index 41cdd693..6d1636c0 100644 --- a/src/MongODM.Core/Tasks/MigrateDbContextTask.cs +++ b/src/MongODM.Core/Tasks/MigrateDbContextTask.cs @@ -76,7 +76,7 @@ public async Task RunAsync(string dbMigrationOpId, string taskId) MigrationLogBase.ExecutionState.Executing)); await dbContext.SaveChangesAsync().ConfigureAwait(false); - await repository.BuildIndexesAsync(dbContext.SchemaRegistry).ConfigureAwait(false); + await repository.BuildIndexesAsync().ConfigureAwait(false); dbMigrationOp.AddLog(new IndexMigrationLog( repository.Name, From 0d41c28e300f5affb6b1fe68a3587555975d0fe6 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Wed, 13 Apr 2022 02:58:21 +0200 Subject: [PATCH 64/78] fixes for use SerializationContextAccessor with mongo library --- .../Extensions/ServiceCollectionExtensions.cs | 6 +++ src/MongODM.Core/DbContext.cs | 6 +++ .../Mapping/Schemas/ModelMapsSchemaBase.cs | 3 ++ .../ModelMapSerializationProvider.cs | 46 +++++++++++++++++++ .../Utility/DbExecutionContextHandler.cs | 10 ++-- .../Utility/SerializationContextAccessor.cs | 24 ++++++++++ 6 files changed, 90 insertions(+), 5 deletions(-) create mode 100644 src/MongODM.Core/Serialization/Providers/ModelMapSerializationProvider.cs create mode 100644 src/MongODM.Core/Utility/SerializationContextAccessor.cs diff --git a/src/MongODM.AspNetCore/Extensions/ServiceCollectionExtensions.cs b/src/MongODM.AspNetCore/Extensions/ServiceCollectionExtensions.cs index cabd71c6..cc42f8cf 100644 --- a/src/MongODM.AspNetCore/Extensions/ServiceCollectionExtensions.cs +++ b/src/MongODM.AspNetCore/Extensions/ServiceCollectionExtensions.cs @@ -83,6 +83,12 @@ public static IMongODMConfiguration AddMongODM( BsonSerializer.RegisterDiscriminatorConvention(typeof(object), new HierarchicalProxyTolerantDiscriminatorConvention("_t", execContext)); + /* For same motive of handle static calls to BsonSerializer.LookupSerializer(Type), + * we need a way to inject a current context accessor. This is a modification on official drivers, + * waiting an official implementation of serialization contexts. + */ + BsonSerializer.SetSerializationContextAccessor(new SerializationContextAccessor(execContext)); + // DbContext internal. //dependencies /***** diff --git a/src/MongODM.Core/DbContext.cs b/src/MongODM.Core/DbContext.cs index 31b34678..50eaebdd 100644 --- a/src/MongODM.Core/DbContext.cs +++ b/src/MongODM.Core/DbContext.cs @@ -26,6 +26,7 @@ using Etherna.MongODM.Core.Serialization; using Etherna.MongODM.Core.Serialization.Mapping; using Etherna.MongODM.Core.Serialization.Modifiers; +using Etherna.MongODM.Core.Serialization.Providers; using Etherna.MongODM.Core.Utility; using System; using System.Collections.Generic; @@ -82,6 +83,9 @@ public void Initialize( SerializerModifierAccessor = dependencies.SerializerModifierAccessor; _serializerRegistry = (BsonSerializerRegistry)dependencies.BsonSerializerRegistry; + // Execute initialization into execution context. + using var dbExecutionContext = new DbExecutionContextHandler(this); + // Initialize internal dependencies. DbCache.Initialize(this); DbMaintainer.Initialize(this); @@ -297,10 +301,12 @@ protected virtual Task SeedAsync() => private void InitializeSerializerRegistry() { //order matters. It's in reverse order of how they'll get consumed + _serializerRegistry.RegisterSerializationProvider(new ModelMapSerializationProvider(this)); _serializerRegistry.RegisterSerializationProvider(new DiscriminatedInterfaceSerializationProvider()); _serializerRegistry.RegisterSerializationProvider(new CollectionsSerializationProvider()); _serializerRegistry.RegisterSerializationProvider(new PrimitiveSerializationProvider()); _serializerRegistry.RegisterSerializationProvider(new AttributedSerializationProvider()); + _serializerRegistry.RegisterSerializationProvider(new TypeMappingSerializationProvider()); _serializerRegistry.RegisterSerializationProvider(new BsonObjectModelSerializationProvider()); } } diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchemaBase.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchemaBase.cs index 2a560d54..0b567ac2 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchemaBase.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchemaBase.cs @@ -116,8 +116,11 @@ protected override void FreezeAction() { // Freeze model maps. ActiveMap.Freeze(); + foreach (var secondaryMap in _secondaryMaps) secondaryMap.Freeze(); + + FallbackModelMap?.Freeze(); } } } diff --git a/src/MongODM.Core/Serialization/Providers/ModelMapSerializationProvider.cs b/src/MongODM.Core/Serialization/Providers/ModelMapSerializationProvider.cs new file mode 100644 index 00000000..b17e2a6b --- /dev/null +++ b/src/MongODM.Core/Serialization/Providers/ModelMapSerializationProvider.cs @@ -0,0 +1,46 @@ +using Etherna.MongoDB.Bson; +using Etherna.MongoDB.Bson.Serialization; +using Etherna.MongODM.Core.Serialization.Serializers; +using System; +using System.Globalization; +using System.Reflection; + +namespace Etherna.MongODM.Core.Serialization.Providers +{ + public class ModelMapSerializationProvider : BsonSerializationProviderBase + { + // Fields. + private readonly DbContext dbContext; + + // Constructor. + public ModelMapSerializationProvider(DbContext dbContext) + { + this.dbContext = dbContext; + } + + // Methods. + public override IBsonSerializer? GetSerializer(Type type, IBsonSerializerRegistry serializerRegistry) + { + if (type == null) + throw new ArgumentNullException(nameof(type)); + + var typeInfo = type.GetTypeInfo(); + if (typeInfo.IsGenericType && typeInfo.ContainsGenericParameters) + { + var message = string.Format(CultureInfo.InvariantCulture, "Generic type {0} has unassigned type parameters.", BsonUtils.GetFriendlyTypeName(type)); + throw new ArgumentException(message, nameof(type)); + } + + if ((typeInfo.IsClass || (typeInfo.IsValueType && !typeInfo.IsPrimitive)) && + !typeof(Array).GetTypeInfo().IsAssignableFrom(type) && + !typeof(Enum).GetTypeInfo().IsAssignableFrom(type)) + { + var modelMapSerializerDefinition = typeof(ModelMapSerializer<>); + var modelMapSerializerType = modelMapSerializerDefinition.MakeGenericType(type); + return (IBsonSerializer)Activator.CreateInstance(modelMapSerializerType, dbContext); + } + + return null; + } + } +} diff --git a/src/MongODM.Core/Utility/DbExecutionContextHandler.cs b/src/MongODM.Core/Utility/DbExecutionContextHandler.cs index 18589a6b..242d48fd 100644 --- a/src/MongODM.Core/Utility/DbExecutionContextHandler.cs +++ b/src/MongODM.Core/Utility/DbExecutionContextHandler.cs @@ -1,6 +1,5 @@ using Etherna.ExecContext; using Etherna.ExecContext.AsyncLocal; -using Etherna.ExecContext.Exceptions; using System; using System.Collections; using System.Collections.Generic; @@ -8,7 +7,7 @@ namespace Etherna.MongODM.Core.Utility { - internal class DbExecutionContextHandler : IDisposable + public sealed class DbExecutionContextHandler : IDisposable { // Consts. private const string HandlerKey = "DbContextExecutionContextHandler"; @@ -52,10 +51,11 @@ public void Dispose() // Static methods. public static IDbContext? TryGetCurrentDbContext(IExecutionContext executionContext) { - if (executionContext.Items is null) - throw new ExecutionContextNotFoundException(); + if (executionContext is null) + throw new ArgumentNullException(nameof(executionContext)); - if (!executionContext.Items.ContainsKey(HandlerKey)) + if (executionContext.Items is null || + !executionContext.Items.ContainsKey(HandlerKey)) return null; var requestes = (ICollection)executionContext.Items[HandlerKey]!; diff --git a/src/MongODM.Core/Utility/SerializationContextAccessor.cs b/src/MongODM.Core/Utility/SerializationContextAccessor.cs new file mode 100644 index 00000000..4bda1f2b --- /dev/null +++ b/src/MongODM.Core/Utility/SerializationContextAccessor.cs @@ -0,0 +1,24 @@ +using Etherna.ExecContext; +using Etherna.MongoDB.Bson.Serialization; + +namespace Etherna.MongODM.Core.Utility +{ + public class SerializationContextAccessor : ISerializationContextAccessor + { + // Fields. + private readonly IExecutionContext executionContext; + + // Constructor. + public SerializationContextAccessor(IExecutionContext executionContext) + { + this.executionContext = executionContext; + } + + // Method. + public IBsonSerializerRegistry? TryGetCurrentBsonSerializerRegistry() + { + var dbContext = DbExecutionContextHandler.TryGetCurrentDbContext(executionContext); + return dbContext?.SerializerRegistry; + } + } +} From c255711cd6b3d6338addb70c7f38646d3c19c3c1 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Wed, 13 Apr 2022 03:48:06 +0200 Subject: [PATCH 65/78] update etherna mongo driver --- src/MongODM.Core/MongODM.Core.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index 4ba168ff..79186b4f 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -24,8 +24,8 @@ - - + + all From d95e8a40e7aa97fae5870f5532fd6e4b424632e1 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Thu, 14 Apr 2022 20:43:13 +0200 Subject: [PATCH 66/78] add option for disable model creation with proxy types --- .../ProxyModels/IProxyGenerator.cs | 4 ++++ .../ProxyModels/ProxyGenerator.cs | 20 ++++++++++++++++--- .../Serializers/ModelMapSerializer.cs | 9 +++++++-- .../Serializers/ReferenceSerializer.cs | 9 +++++++-- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/MongODM.Core/ProxyModels/IProxyGenerator.cs b/src/MongODM.Core/ProxyModels/IProxyGenerator.cs index b34bb1dd..55d23687 100644 --- a/src/MongODM.Core/ProxyModels/IProxyGenerator.cs +++ b/src/MongODM.Core/ProxyModels/IProxyGenerator.cs @@ -18,6 +18,10 @@ namespace Etherna.MongODM.Core.ProxyModels { public interface IProxyGenerator { + // Properties. + bool DisableCreationWithProxyTypes { get; set; } + + // Methods. object CreateInstance(Type type, IDbContext dbContext, params object[] constructorArguments); TModel CreateInstance(IDbContext dbContext, params object[] constructorArguments); bool IsProxyType(Type type); diff --git a/src/MongODM.Core/ProxyModels/ProxyGenerator.cs b/src/MongODM.Core/ProxyModels/ProxyGenerator.cs index 7cfd148d..7a24f97a 100644 --- a/src/MongODM.Core/ProxyModels/ProxyGenerator.cs +++ b/src/MongODM.Core/ProxyModels/ProxyGenerator.cs @@ -17,6 +17,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Threading; namespace Etherna.MongODM.Core.ProxyModels @@ -34,14 +35,13 @@ public class ProxyGenerator : IProxyGenerator, IDisposable private readonly Dictionary proxyTypeDictionary = new(); private readonly ReaderWriterLockSlim proxyTypeDictionaryLock = new(LockRecursionPolicy.SupportsRecursion); - // Constructors. + // Constructor and dispose. public ProxyGenerator( Castle.DynamicProxy.IProxyGenerator proxyGeneratorCore) { this.proxyGeneratorCore = proxyGeneratorCore; } - - // Dispose. + public void Dispose() { Dispose(true); @@ -62,6 +62,9 @@ protected virtual void Dispose(bool disposing) disposed = true; } + // Properties. + public bool DisableCreationWithProxyTypes { get; set; } + // Methods. public object CreateInstance( Type type, @@ -73,6 +76,17 @@ public object CreateInstance( if (type is null) throw new ArgumentNullException(nameof(type)); + // If creation of proxy models are disabled, create a simple model instance. + if (DisableCreationWithProxyTypes) + { + return Activator.CreateInstance( + type, + BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, + null, + constructorArguments, + null); + } + // Get configuration. (Type[] AdditionalInterfaces, Func InterceptorInstancerSelector) configuration = (null!, null!); modelConfigurationDictionaryLock.EnterReadLock(); diff --git a/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs index 26e476a4..284dd1ec 100644 --- a/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs @@ -152,9 +152,14 @@ public override TModel Deserialize(BsonDeserializationContext context, BsonDeser model = DeserializeModelMapHelper(actualTypeSchema.ActiveMap, localContext, args); } - // Add model to cache. + // Add model to cache (if proxy). + /* Proxy models enable different features. Anyway, if the model as not been created as a proxy + * (for example for tests scope) these additional operations are not possible or required. + * In this case, don't add any not-proxy models in cache. + */ if (!dbContext.SerializerModifierAccessor.IsNoCacheEnabled && - GetDocumentId(model, out var id, out _, out _) && id != null) + GetDocumentId(model, out var id, out _, out _) && id != null && + dbContext.ProxyGenerator.IsProxyType(model.GetType())) { if (dbContext.DbCache.LoadedModels.ContainsKey(id)) { diff --git a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs index 53466474..b09dc86b 100644 --- a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializer.cs @@ -149,8 +149,13 @@ public override TModelBase Deserialize(BsonDeserializationContext context, BsonD var model = serializer.Deserialize(localContext, args) as TModelBase; - // Process model. - if (model != null) + // Process model (if proxy). + /* Proxy models enable different features. Anyway, if the model as not been created as a proxy + * (for example for tests scope) these additional operations are not possible or required. + * In this case, simply return the model as is. + */ + if (model != null && + dbContext.ProxyGenerator.IsProxyType(model.GetType())) { var id = model.Id; if (id == null) //ignore refered instances without id From d04ea05ce6071bf0d5e596f47e5051c1f226ed7e Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Thu, 14 Apr 2022 20:48:29 +0200 Subject: [PATCH 67/78] fix tests --- test/MongODM.Core.Tests/ModelMapSerializerTest.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/MongODM.Core.Tests/ModelMapSerializerTest.cs b/test/MongODM.Core.Tests/ModelMapSerializerTest.cs index 282e5b3e..9454891b 100644 --- a/test/MongODM.Core.Tests/ModelMapSerializerTest.cs +++ b/test/MongODM.Core.Tests/ModelMapSerializerTest.cs @@ -100,6 +100,8 @@ public ModelMapSerializerTest() .Returns(() => dbCacheMock.Object); dbContextMock.Setup(c => c.DiscriminatorRegistry) .Returns(() => discriminatorRegistryMock.Object); + dbContextMock.Setup(c => c.ProxyGenerator.IsProxyType(It.IsAny())) + .Returns(true); dbContextMock.Setup(c => c.Options.DocumentSemVer) .Returns(() => documentSemVerOptions); dbContextMock.Setup(c => c.Options.ModelMapVersion) From 8ba8576c6ca3a598d58d7899fbbc3f55af805fa6 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Fri, 15 Apr 2022 01:07:26 +0200 Subject: [PATCH 68/78] remove ModelMapSerializer constructor constumization other refactoring --- .../Domain/ModelMaps/OperationBaseMap.cs | 8 +-- .../Serialization/Mapping/IModelMap.cs | 15 ++++- .../Serialization/Mapping/ModelMap.cs | 36 +++++++++++- .../Serialization/Mapping/SchemaRegistry.cs | 4 +- .../Schemas/IModelMapsSchemaBuilder.cs | 14 ----- .../Mapping/Schemas/ModelMapsSchema.cs | 23 +------- .../ModelMapDeserializationContext.cs | 18 ------ .../Serializers/ModelMapSerializer.cs | 57 +++++++++---------- .../ReferenceSerializerConfiguration.cs | 1 + .../ModelMapSerializerTest.cs | 3 + 10 files changed, 80 insertions(+), 99 deletions(-) delete mode 100644 src/MongODM.Core/Serialization/Serializers/ModelMapDeserializationContext.cs diff --git a/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs b/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs index e75017f1..d8715a6f 100644 --- a/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs +++ b/src/MongODM.Core/Domain/ModelMaps/OperationBaseMap.cs @@ -13,7 +13,6 @@ // limitations under the License. using Etherna.MongODM.Core.Domain.Models; -using Etherna.MongODM.Core.Options; using Etherna.MongODM.Core.Serialization; using Etherna.MongODM.Core.Serialization.Serializers; @@ -25,12 +24,7 @@ public void Register(IDbContext dbContext) { dbContext.SchemaRegistry.AddModelMapsSchema("ee726d4f-6e6a-44b0-bf3e-45322534c36d", customSerializer: new ModelMapSerializer( - dbContext, - overrideDocumentSemVerOptions: new DocumentSemVerOptions - { - CurrentVersion = dbContext.LibraryVersion, - WriteInDocuments = false - })); + dbContext)); } } } diff --git a/src/MongODM.Core/Serialization/Mapping/IModelMap.cs b/src/MongODM.Core/Serialization/Mapping/IModelMap.cs index ff800a9e..9ba90ce0 100644 --- a/src/MongODM.Core/Serialization/Mapping/IModelMap.cs +++ b/src/MongODM.Core/Serialization/Mapping/IModelMap.cs @@ -13,8 +13,10 @@ // limitations under the License. using Etherna.MongoDB.Bson.Serialization; +using Etherna.MongODM.Core.Serialization.Serializers; using Etherna.MongODM.Core.Utility; using System; +using System.Threading.Tasks; namespace Etherna.MongODM.Core.Serialization.Mapping { @@ -25,12 +27,19 @@ public interface IModelMap : IFreezableConfig string? BaseModelMapId { get; } BsonClassMap BsonClassMap { get; } IBsonSerializer BsonClassMapSerializer { get; } - public bool IsEntity { get; } - public Type ModelType { get; } - public IBsonSerializer? Serializer { get; } + bool IsEntity { get; } + Type ModelType { get; } + IBsonSerializer? Serializer { get; } // Methods. + Task FixDeserializedModelAsync(object model); void SetBaseModelMap(IModelMap baseModelMap); void UseProxyGenerator(IDbContext dbContext); } + + public interface IModelMap : IModelMap + { + // Methods. + Task FixDeserializedModelAsync(TModel model); + } } \ No newline at end of file diff --git a/src/MongODM.Core/Serialization/Mapping/ModelMap.cs b/src/MongODM.Core/Serialization/Mapping/ModelMap.cs index 0a203aca..5bb0c1a6 100644 --- a/src/MongODM.Core/Serialization/Mapping/ModelMap.cs +++ b/src/MongODM.Core/Serialization/Mapping/ModelMap.cs @@ -19,6 +19,7 @@ using System; using System.Linq; using System.Reflection; +using System.Threading.Tasks; namespace Etherna.MongODM.Core.Serialization.Mapping { @@ -65,6 +66,9 @@ public IBsonSerializer BsonClassMapSerializer public IBsonSerializer? Serializer { get; } // Methods. + public Task FixDeserializedModelAsync(object model) => + FixDeserializedModelHelperAsync(model); + public void SetBaseModelMap(IModelMap baseModelMap) => ExecuteConfigAction(() => { @@ -104,6 +108,8 @@ public void UseProxyGenerator(IDbContext dbContext) => }); // Protected methods. + protected abstract Task FixDeserializedModelHelperAsync(object model); + protected override void FreezeAction() { // Freeze bson class maps. @@ -121,15 +127,41 @@ public static IBsonSerializer GetDefaultSerializer(IDbContext db } } - public class ModelMap : ModelMap + public class ModelMap : ModelMap, IModelMap { + private readonly Func>? fixDeserializedModelFunc; + // Constructors. public ModelMap( string id, BsonClassMap bsonClassMap, string? baseModelMapId = null, + Func>? fixDeserializedModelFunc = null, IBsonSerializer? serializer = null) : base(id, baseModelMapId, bsonClassMap, serializer) - { } + { + this.fixDeserializedModelFunc = fixDeserializedModelFunc; + } + + // Methods. + public async Task FixDeserializedModelAsync(TModel model) + { + if (model is null) + throw new ArgumentNullException(nameof(model)); + + return (TModel)await FixDeserializedModelHelperAsync(model).ConfigureAwait(false); + } + + // Protected methods. + protected override async Task FixDeserializedModelHelperAsync( + object model) + { + if (model is null) + throw new ArgumentNullException(nameof(model)); + + return fixDeserializedModelFunc is not null ? + (await fixDeserializedModelFunc((TModel)model).ConfigureAwait(false))! : + model; + } } } diff --git a/src/MongODM.Core/Serialization/Mapping/SchemaRegistry.cs b/src/MongODM.Core/Serialization/Mapping/SchemaRegistry.cs index bf584066..88eb12af 100644 --- a/src/MongODM.Core/Serialization/Mapping/SchemaRegistry.cs +++ b/src/MongODM.Core/Serialization/Mapping/SchemaRegistry.cs @@ -79,8 +79,7 @@ public IModelMapsSchemaBuilder AddModelMapsSchema( var modelMap = new ModelMap( activeModelMapId, new BsonClassMap(activeModelMapInitializer ?? (cm => cm.AutoMap())), - null, - customSerializer ?? ModelMap.GetDefaultSerializer(dbContext)); + serializer: customSerializer ?? ModelMap.GetDefaultSerializer(dbContext)); return AddModelMapsSchema(modelMap); } @@ -355,6 +354,7 @@ private IModelMapsSchema CreateNewDefaultModelMapsSchema(Type modelType) Guid.NewGuid().ToString(), //string id classMap, //BsonClassMap bsonClassMap null, //string? baseModelMapId + null, //Func>? fixDeserializedModelFunc null); //IBsonSerializer? serializer //model maps schema diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchemaBuilder.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchemaBuilder.cs index 2d02677b..5a3f0f7e 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchemaBuilder.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/IModelMapsSchemaBuilder.cs @@ -48,20 +48,6 @@ IModelMapsSchemaBuilder AddFallbackModelMap( IModelMapsSchemaBuilder AddFallbackModelMap( ModelMap modelMap); - /// - /// Register a secondary model map - /// - /// The map Id - /// The model map inizializer - /// Id of the base model map for this model map - /// Custom serializer - /// This same model schema configuration - IModelMapsSchemaBuilder AddSecondaryMap( - string id, - Action>? modelMapInitializer = null, - string? baseModelMapId = null, - IBsonSerializer? customSerializer = null); - /// /// Register a secondary model map /// diff --git a/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchema.cs b/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchema.cs index 4cb07010..1cc95dfa 100644 --- a/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchema.cs +++ b/src/MongODM.Core/Serialization/Mapping/Schemas/ModelMapsSchema.cs @@ -44,7 +44,7 @@ public IModelMapsSchemaBuilder AddFallbackModelMap( "fallback", new BsonClassMap(modelMapInitializer ?? (cm => cm.AutoMap())), baseModelMapId, - customSerializer)); + serializer: customSerializer)); public IModelMapsSchemaBuilder AddFallbackModelMap(ModelMap modelMap) { @@ -52,27 +52,6 @@ public IModelMapsSchemaBuilder AddFallbackModelMap(ModelMap mode return this; } - [SuppressMessage("Reliability", "CA2000:Dispose objects before losing scope", Justification = "The new model map instance can't be disposed")] - public IModelMapsSchemaBuilder AddSecondaryMap( - string id, - Action>? modelMapInitializer = null, - string? baseModelMapId = null, - IBsonSerializer? customSerializer = null) - { - // Verify if needs a default serializer. - if (!typeof(TModel).IsAbstract) - customSerializer ??= ModelMap.GetDefaultSerializer(DbContext); - - // Create model map. - var modelMap = new ModelMap( - id, - new BsonClassMap(modelMapInitializer ?? (cm => cm.AutoMap())), - baseModelMapId, - customSerializer); - - return AddSecondaryMap(modelMap); - } - public IModelMapsSchemaBuilder AddSecondaryMap(ModelMap modelMap) { AddSecondaryMapHelper(modelMap); diff --git a/src/MongODM.Core/Serialization/Serializers/ModelMapDeserializationContext.cs b/src/MongODM.Core/Serialization/Serializers/ModelMapDeserializationContext.cs deleted file mode 100644 index 25d0bdca..00000000 --- a/src/MongODM.Core/Serialization/Serializers/ModelMapDeserializationContext.cs +++ /dev/null @@ -1,18 +0,0 @@ -namespace Etherna.MongODM.Core.Serialization.Serializers -{ - public class ModelMapDeserializationContext - { - // Constructor. - public ModelMapDeserializationContext( - string? modelMapId, - SemanticVersion? semVer) - { - ModelMapId = modelMapId; - SemVer = semVer; - } - - // Properties. - public string? ModelMapId { get; } - public SemanticVersion? SemVer { get; } - } -} diff --git a/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs b/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs index 284dd1ec..4b7a0cef 100644 --- a/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs +++ b/src/MongODM.Core/Serialization/Serializers/ModelMapSerializer.cs @@ -18,7 +18,6 @@ using Etherna.MongoDB.Bson.Serialization.Conventions; using Etherna.MongoDB.Bson.Serialization.Serializers; using Etherna.MongODM.Core.Domain.Models; -using Etherna.MongODM.Core.Options; using Etherna.MongODM.Core.ProxyModels; using Etherna.MongODM.Core.Serialization.Mapping; using System; @@ -36,30 +35,19 @@ public class ModelMapSerializer : private IDiscriminatorConvention _discriminatorConvention = default!; private readonly BsonElement documentSemVerElement; private readonly IDbContext dbContext; - private readonly DocumentSemVerOptions documentSemVerOptions; - private readonly Func> fixDeserializedModelAsync; - private readonly ModelMapVersionOptions modelMapVersionOptions; // Constructor. public ModelMapSerializer( - IDbContext dbContext, - Func>? fixDeserializedModelAsync = null, - DocumentSemVerOptions? overrideDocumentSemVerOptions = null, - ModelMapVersionOptions? overrideModelMapVersionOptions = null) + IDbContext dbContext) { if (dbContext is null) throw new ArgumentNullException(nameof(dbContext)); this.dbContext = dbContext; - this.fixDeserializedModelAsync = fixDeserializedModelAsync ?? ((m, _) => Task.FromResult(m)); - - documentSemVerOptions = overrideDocumentSemVerOptions ?? dbContext.Options.DocumentSemVer; - modelMapVersionOptions = overrideModelMapVersionOptions ?? dbContext.Options.ModelMapVersion; - documentSemVerElement = new BsonElement( - documentSemVerOptions.ElementName, - documentSemVerOptions.CurrentVersion.ToBsonArray()); + dbContext.Options.DocumentSemVer.ElementName, + dbContext.Options.DocumentSemVer.CurrentVersion.ToBsonArray()); } // Properties. @@ -102,7 +90,7 @@ public override TModel Deserialize(BsonDeserializationContext context, BsonDeser //get version SemanticVersion? documentSemVer = null; - if (bsonDocument.TryGetElement(documentSemVerOptions.ElementName, out BsonElement versionElement)) + if (bsonDocument.TryGetElement(dbContext.Options.DocumentSemVer.ElementName, out BsonElement versionElement)) { documentSemVer = BsonValueToSemVer(versionElement.Value); bsonDocument.RemoveElement(versionElement); //don't report into extra elements @@ -110,7 +98,7 @@ public override TModel Deserialize(BsonDeserializationContext context, BsonDeser //get model map id string? modelMapId = null; - if (bsonDocument.TryGetElement(modelMapVersionOptions.ElementName, out BsonElement modelMapIdElement)) + if (bsonDocument.TryGetElement(dbContext.Options.ModelMapVersion.ElementName, out BsonElement modelMapIdElement)) { modelMapId = BsonValueToModelMapId(modelMapIdElement.Value); bsonDocument.RemoveElement(modelMapIdElement); //don't report into extra elements @@ -131,7 +119,9 @@ public override TModel Deserialize(BsonDeserializationContext context, BsonDeser //if a correct model map is identified with its id if (modelMapId != null && actualTypeSchema.AllMapsDictionary.ContainsKey(modelMapId)) { - model = DeserializeModelMapHelper(actualTypeSchema.AllMapsDictionary[modelMapId], localContext, args); + var task = DeserializeModelMapHelperAsync(actualTypeSchema.AllMapsDictionary[modelMapId], localContext, args); + task.Wait(); + model = task.Result; } //else, if a fallback serializator exists @@ -143,13 +133,17 @@ public override TModel Deserialize(BsonDeserializationContext context, BsonDeser //else, if a fallback model map exists else if (actualTypeSchema.FallbackModelMap != null) { - model = DeserializeModelMapHelper(actualTypeSchema.FallbackModelMap, localContext, args); + var task = DeserializeModelMapHelperAsync(actualTypeSchema.FallbackModelMap, localContext, args); + task.Wait(); + model = task.Result; } //else, deserialize wih current active model map else { - model = DeserializeModelMapHelper(actualTypeSchema.ActiveMap, localContext, args); + var task = DeserializeModelMapHelperAsync(actualTypeSchema.ActiveMap, localContext, args); + task.Wait(); + model = task.Result; } // Add model to cache (if proxy). @@ -175,11 +169,6 @@ public override TModel Deserialize(BsonDeserializationContext context, BsonDeser } } - // Fix model. - var task = fixDeserializedModelAsync(model, new ModelMapDeserializationContext(modelMapId, documentSemVer)); - task.Wait(); - model = task.Result; - // Enable auditing. (model as IAuditable)?.EnableAuditing(); @@ -230,14 +219,14 @@ public override void Serialize(BsonSerializationContext context, BsonSerializati * from bson class map serializer. In that case, the right model map id is already be setted, and we * don't have to replace it with the one wrong of the basic collection model type. */ - if (!bsonDocument.Contains(modelMapVersionOptions.ElementName)) + if (!bsonDocument.Contains(dbContext.Options.ModelMapVersion.ElementName)) bsonDocument.InsertAt(0, dbContext.SchemaRegistry.GetActiveModelMapIdBsonElement(actualType)); //add version - if (documentSemVerOptions.WriteInDocuments && bsonWriter.IsRootDocument) + if (dbContext.Options.DocumentSemVer.WriteInDocuments && bsonWriter.IsRootDocument) { - if (bsonDocument.Contains(documentSemVerOptions.ElementName)) - bsonDocument.Remove(documentSemVerOptions.ElementName); + if (bsonDocument.Contains(dbContext.Options.DocumentSemVer.ElementName)) + bsonDocument.Remove(dbContext.Options.DocumentSemVer.ElementName); bsonDocument.InsertAt(1, documentSemVerElement); } @@ -273,7 +262,10 @@ public bool TryGetMemberSerializationInfo(string memberName, out BsonSerializati _ => throw new NotSupportedException(), }; - private static TModel DeserializeModelMapHelper(IModelMap modelMap, BsonDeserializationContext context, BsonDeserializationArgs args) + private static async Task DeserializeModelMapHelperAsync( + IModelMap modelMap, + BsonDeserializationContext context, + BsonDeserializationArgs args) { /* If is mapped a different serializer than the current one, choose it. * Otherwise, if doesn't exist or is already the current, deserialize with BsonClassMap @@ -282,7 +274,10 @@ private static TModel DeserializeModelMapHelper(IModelMap modelMap, BsonDeserial modelMap.Serializer : modelMap.BsonClassMapSerializer; - return (TModel)serializer.Deserialize(context, args); + var model = (TModel)serializer.Deserialize(context, args); + + // Fix model. + return (TModel)await modelMap.FixDeserializedModelAsync(model).ConfigureAwait(false); } } } diff --git a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerConfiguration.cs b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerConfiguration.cs index 7ea239c3..cbac623c 100644 --- a/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerConfiguration.cs +++ b/src/MongODM.Core/Serialization/Serializers/ReferenceSerializerConfiguration.cs @@ -160,6 +160,7 @@ private IModelMapsSchema CreateNewDefaultReferenceSchema(Type modelType) Guid.NewGuid().ToString(), //string id classMap, //BsonClassMap bsonClassMap null, //string? baseModelMapId + null, //Func>? fixDeserializedModelFunc null); //IBsonSerializer? serializer //model maps schema diff --git a/test/MongODM.Core.Tests/ModelMapSerializerTest.cs b/test/MongODM.Core.Tests/ModelMapSerializerTest.cs index 9454891b..edf6b8c9 100644 --- a/test/MongODM.Core.Tests/ModelMapSerializerTest.cs +++ b/test/MongODM.Core.Tests/ModelMapSerializerTest.cs @@ -28,6 +28,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Xunit; namespace Etherna.MongODM.Core @@ -162,6 +163,8 @@ public void Deserialize(DeserializationTestElement test) modelMapsSchemaMock.Setup(s => s.ActiveMap.BsonClassMapSerializer) .Returns(bsonClassMapSerializer); + modelMapsSchemaMock.Setup(s => s.ActiveMap.FixDeserializedModelAsync(It.IsAny())) + .Returns(m => Task.FromResult(m)); // Action test.PreAction(bsonReader); From 1caf21766f6ce2541faf3395b909b8ed8fbf3970 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Mon, 18 Apr 2022 23:34:18 +0200 Subject: [PATCH 69/78] add possibility to construct ModelMap with only Id --- src/MongODM.Core/Serialization/Mapping/ModelMap.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/MongODM.Core/Serialization/Mapping/ModelMap.cs b/src/MongODM.Core/Serialization/Mapping/ModelMap.cs index 5bb0c1a6..476cd0fb 100644 --- a/src/MongODM.Core/Serialization/Mapping/ModelMap.cs +++ b/src/MongODM.Core/Serialization/Mapping/ModelMap.cs @@ -134,11 +134,11 @@ public class ModelMap : ModelMap, IModelMap // Constructors. public ModelMap( string id, - BsonClassMap bsonClassMap, + BsonClassMap? bsonClassMap = null, string? baseModelMapId = null, Func>? fixDeserializedModelFunc = null, IBsonSerializer? serializer = null) - : base(id, baseModelMapId, bsonClassMap, serializer) + : base(id, baseModelMapId, bsonClassMap ?? new BsonClassMap(), serializer) { this.fixDeserializedModelFunc = fixDeserializedModelFunc; } From db1180723010ccdbfcb8e317c15db02d4eb51b58 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Tue, 19 Apr 2022 01:05:13 +0200 Subject: [PATCH 70/78] fix issue --- src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj | 2 +- src/MongODM.AspNetCore/MongODM.AspNetCore.csproj | 2 +- src/MongODM.Core/MongODM.Core.csproj | 2 +- src/MongODM.Core/Serialization/Mapping/ModelMap.cs | 2 +- src/MongODM.Hangfire/MongODM.Hangfire.csproj | 2 +- src/MongODM/MongODM.csproj | 2 +- 6 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj index aa60df38..ff55b0a3 100644 --- a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj +++ b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj @@ -32,7 +32,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj index ca416f2a..3c556a61 100644 --- a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj +++ b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj @@ -32,7 +32,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index 79186b4f..746008f4 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -27,7 +27,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.Core/Serialization/Mapping/ModelMap.cs b/src/MongODM.Core/Serialization/Mapping/ModelMap.cs index 476cd0fb..b56bd7e2 100644 --- a/src/MongODM.Core/Serialization/Mapping/ModelMap.cs +++ b/src/MongODM.Core/Serialization/Mapping/ModelMap.cs @@ -138,7 +138,7 @@ public ModelMap( string? baseModelMapId = null, Func>? fixDeserializedModelFunc = null, IBsonSerializer? serializer = null) - : base(id, baseModelMapId, bsonClassMap ?? new BsonClassMap(), serializer) + : base(id, baseModelMapId, bsonClassMap ?? new BsonClassMap(cm => cm.AutoMap()), serializer) { this.fixDeserializedModelFunc = fixDeserializedModelFunc; } diff --git a/src/MongODM.Hangfire/MongODM.Hangfire.csproj b/src/MongODM.Hangfire/MongODM.Hangfire.csproj index e2c65d7e..23d853bd 100644 --- a/src/MongODM.Hangfire/MongODM.Hangfire.csproj +++ b/src/MongODM.Hangfire/MongODM.Hangfire.csproj @@ -23,7 +23,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index b1e8630d..ed8196f8 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -27,7 +27,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From 393932cc4b692e4f09d22da4e26feec621f2c6ed Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Fri, 13 May 2022 19:39:19 +0200 Subject: [PATCH 71/78] update dependencies --- src/MongODM.Core/MongODM.Core.csproj | 6 +++--- test/MongODM.Core.Tests/MongODM.Core.Tests.csproj | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index 746008f4..39058a9d 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -23,9 +23,9 @@ - - - + + + all diff --git a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj index 76122349..5452ff3c 100644 --- a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj +++ b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj @@ -9,10 +9,10 @@ - - + + - + all runtime; build; native; contentfiles; analyzers From 4a3075b2740fb8f77cf8b3bf7d4fc2dfd13b8f25 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Mon, 30 May 2022 01:08:56 +0200 Subject: [PATCH 72/78] remove seeding middleware --- .../Persistence/SampleDbContext.cs | 8 ++++ samples/AspNetCoreSample/Startup.cs | 2 + .../ApplicationBuilderExtensions.cs | 35 ++++++++++++-- .../DbContextsSeedingMiddleware.cs | 48 ------------------- 4 files changed, 42 insertions(+), 51 deletions(-) delete mode 100644 src/MongODM.AspNetCore/Middlewares/DbContextsSeedingMiddleware.cs diff --git a/samples/AspNetCoreSample/Persistence/SampleDbContext.cs b/samples/AspNetCoreSample/Persistence/SampleDbContext.cs index 0bbc0d62..36fa463b 100644 --- a/samples/AspNetCoreSample/Persistence/SampleDbContext.cs +++ b/samples/AspNetCoreSample/Persistence/SampleDbContext.cs @@ -18,6 +18,7 @@ using Etherna.MongODM.Core.Repositories; using Etherna.MongODM.Core.Serialization; using System.Collections.Generic; +using System.Threading.Tasks; namespace Etherna.MongODM.AspNetCoreSample.Persistence { @@ -31,5 +32,12 @@ public class SampleDbContext : DbContext, ISampleDbContext new ModelBaseMap(), new CatMap() }; + + protected override Task SeedAsync() + { + // Seed here. + + return base.SeedAsync(); + } } } diff --git a/samples/AspNetCoreSample/Startup.cs b/samples/AspNetCoreSample/Startup.cs index ab67c0ea..54282c0f 100644 --- a/samples/AspNetCoreSample/Startup.cs +++ b/samples/AspNetCoreSample/Startup.cs @@ -60,6 +60,8 @@ public void Configure(IApplicationBuilder app) { endpoints.MapRazorPages(); }); + + app.SeedDbContexts(); } } } diff --git a/src/MongODM.AspNetCore/Extensions/ApplicationBuilderExtensions.cs b/src/MongODM.AspNetCore/Extensions/ApplicationBuilderExtensions.cs index d32fe1e5..88e55007 100644 --- a/src/MongODM.AspNetCore/Extensions/ApplicationBuilderExtensions.cs +++ b/src/MongODM.AspNetCore/Extensions/ApplicationBuilderExtensions.cs @@ -1,14 +1,43 @@ -using Etherna.MongODM.AspNetCore.Middlewares; +using Etherna.ExecContext.AsyncLocal; +using Etherna.MongODM.Core; +using Etherna.MongODM.Core.Options; using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; namespace Etherna.MongODM { public static class ApplicationBuilderExtensions { - public static IApplicationBuilder UseDbContextsSeeding( + public static IApplicationBuilder SeedDbContexts( this IApplicationBuilder builder) { - return builder.UseMiddleware(); + if (builder is null) + throw new ArgumentNullException(nameof(builder)); + + var serviceProvider = builder.ApplicationServices; + var mongODMOptions = serviceProvider.GetRequiredService>(); + + // Get dbcontext instances. + var dbContextTypes = mongODMOptions.Value.DbContextTypes; + var dbContexts = dbContextTypes.Select(type => (IDbContext)serviceProvider.GetRequiredService(type)); + + // Create an execution context. + using var execContext = AsyncLocalContext.Instance.InitAsyncLocalContext(); + + // Seed all dbcontexts. + var tasks = new List(); + foreach (var dbContext in dbContexts) + if (!dbContext.IsSeeded) + tasks.Add(dbContext.SeedIfNeededAsync()); + + Task.WaitAll(tasks.ToArray()); + + return builder; } } } diff --git a/src/MongODM.AspNetCore/Middlewares/DbContextsSeedingMiddleware.cs b/src/MongODM.AspNetCore/Middlewares/DbContextsSeedingMiddleware.cs deleted file mode 100644 index 80c03bf4..00000000 --- a/src/MongODM.AspNetCore/Middlewares/DbContextsSeedingMiddleware.cs +++ /dev/null @@ -1,48 +0,0 @@ -using Etherna.MongODM.Core; -using Etherna.MongODM.Core.Options; -using Microsoft.AspNetCore.Http; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace Etherna.MongODM.AspNetCore.Middlewares -{ - public class DbContextsSeedingMiddleware - { - // Fields. - private readonly RequestDelegate next; - private readonly IEnumerable dbContexts; - - // Constructor. - public DbContextsSeedingMiddleware( - RequestDelegate next, - IOptions mongODMOptions, - IServiceProvider serviceProvider) - { - if (mongODMOptions is null) - throw new ArgumentNullException(nameof(mongODMOptions)); - - this.next = next; - var dbContextTypes = mongODMOptions.Value.DbContextTypes; - - // Get dbcontext instances (cache them). - dbContexts = dbContextTypes.Select(type => (IDbContext)serviceProvider.GetRequiredService(type)) - .ToList(); - } - - // Methods. - public async Task InvokeAsync(HttpContext context) - { - // Seed all dbcontexts. - foreach (var dbContext in dbContexts) - if (!dbContext.IsSeeded) - await dbContext.SeedIfNeededAsync().ConfigureAwait(false); - - // Call the next delegate/middleware in the pipeline. - await next(context).ConfigureAwait(false); - } - } -} From d759fe48d4abeb84aa00397446c9f32e86891107 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Mon, 30 May 2022 01:17:40 +0200 Subject: [PATCH 73/78] remove dotnet5 --- .github/workflows/myget-unstable-deploy.yml | 1 - .github/workflows/nuget-stable-deploy.yml | 1 - samples/AspNetCoreSample/AspNetCoreSample.csproj | 2 +- src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj | 2 +- src/MongODM.AspNetCore/MongODM.AspNetCore.csproj | 2 +- src/MongODM/MongODM.csproj | 2 +- 6 files changed, 4 insertions(+), 6 deletions(-) diff --git a/.github/workflows/myget-unstable-deploy.yml b/.github/workflows/myget-unstable-deploy.yml index 907453f4..7ad35bca 100644 --- a/.github/workflows/myget-unstable-deploy.yml +++ b/.github/workflows/myget-unstable-deploy.yml @@ -20,7 +20,6 @@ jobs: with: dotnet-version: | 3.1.x - 5.0.x 6.0.x - name: Build with dotnet diff --git a/.github/workflows/nuget-stable-deploy.yml b/.github/workflows/nuget-stable-deploy.yml index ebe21826..e29a2fd1 100644 --- a/.github/workflows/nuget-stable-deploy.yml +++ b/.github/workflows/nuget-stable-deploy.yml @@ -19,7 +19,6 @@ jobs: with: dotnet-version: | 3.1.x - 5.0.x 6.0.x - name: Build with dotnet diff --git a/samples/AspNetCoreSample/AspNetCoreSample.csproj b/samples/AspNetCoreSample/AspNetCoreSample.csproj index bd638c65..a190c614 100644 --- a/samples/AspNetCoreSample/AspNetCoreSample.csproj +++ b/samples/AspNetCoreSample/AspNetCoreSample.csproj @@ -1,7 +1,7 @@ - net5.0 + net6.0 Etherna.MongODM.AspNetCoreSample Etherna Sagl diff --git a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj index ff55b0a3..87e0b789 100644 --- a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj +++ b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1;net5.0;net6.0 + netcoreapp3.1;net6.0 true true Etherna.MongODM.AspNetCore.UI diff --git a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj index 3c556a61..5a6bdbe5 100644 --- a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj +++ b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1;net5.0;net6.0 + netcoreapp3.1;net6.0 true Etherna.MongODM.AspNetCore Etherna Sagl diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index ed8196f8..bdc72961 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -1,7 +1,7 @@  - netcoreapp3.1;net5.0;net6.0 + netcoreapp3.1;net6.0 true Etherna.MongODM Etherna Sagl From 2f3f8a0baee79a36d7114bb3d661ab23975d35c2 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Mon, 30 May 2022 01:29:44 +0200 Subject: [PATCH 74/78] update dependencies --- src/MongODM.AspNetCore/MongODM.AspNetCore.csproj | 2 +- src/MongODM.Core/MongODM.Core.csproj | 2 +- src/MongODM/MongODM.csproj | 2 +- test/MongODM.Core.Tests/MongODM.Core.Tests.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj index 5a6bdbe5..71e8d93d 100644 --- a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj +++ b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj @@ -31,7 +31,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index 39058a9d..be28b3e3 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -26,7 +26,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index bdc72961..194c8eec 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -31,7 +31,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj index 5452ff3c..882fcc64 100644 --- a/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj +++ b/test/MongODM.Core.Tests/MongODM.Core.Tests.csproj @@ -10,7 +10,7 @@ - + all From 915628099c10e77c81fcbfac965d71c2f6e7d070 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Tue, 7 Jun 2022 14:48:11 +0200 Subject: [PATCH 75/78] update mongo drivers --- src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj | 2 +- src/MongODM.AspNetCore/MongODM.AspNetCore.csproj | 2 +- src/MongODM.Core/MongODM.Core.csproj | 6 +++--- src/MongODM.Hangfire/MongODM.Hangfire.csproj | 2 +- src/MongODM/MongODM.csproj | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj index 87e0b789..c5b3929b 100644 --- a/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj +++ b/src/MongODM.AspNetCore.UI/MongODM.AspNetCore.UI.csproj @@ -32,7 +32,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj index 71e8d93d..4c93967a 100644 --- a/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj +++ b/src/MongODM.AspNetCore/MongODM.AspNetCore.csproj @@ -32,7 +32,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.Core/MongODM.Core.csproj b/src/MongODM.Core/MongODM.Core.csproj index be28b3e3..fe334434 100644 --- a/src/MongODM.Core/MongODM.Core.csproj +++ b/src/MongODM.Core/MongODM.Core.csproj @@ -24,10 +24,10 @@ - - + + - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM.Hangfire/MongODM.Hangfire.csproj b/src/MongODM.Hangfire/MongODM.Hangfire.csproj index 23d853bd..36f5cd67 100644 --- a/src/MongODM.Hangfire/MongODM.Hangfire.csproj +++ b/src/MongODM.Hangfire/MongODM.Hangfire.csproj @@ -23,7 +23,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/MongODM/MongODM.csproj b/src/MongODM/MongODM.csproj index 194c8eec..c72b23f6 100644 --- a/src/MongODM/MongODM.csproj +++ b/src/MongODM/MongODM.csproj @@ -27,7 +27,7 @@ - + all runtime; build; native; contentfiles; analyzers; buildtransitive From cf4028478fda60fd5a040201e5f85367cc631727 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Wed, 15 Jun 2022 19:27:08 +0200 Subject: [PATCH 76/78] handle db migration failure --- .../Domain/Models/DbMigrationOperation.cs | 14 +++- .../Migration/DocumentMigration.cs | 69 ++++++++++--------- src/MongODM.Core/Migration/MigrationResult.cs | 13 ++-- .../Tasks/MigrateDbContextTask.cs | 30 ++++++-- 4 files changed, 85 insertions(+), 41 deletions(-) diff --git a/src/MongODM.Core/Domain/Models/DbMigrationOperation.cs b/src/MongODM.Core/Domain/Models/DbMigrationOperation.cs index 5c931fba..caecdc8b 100644 --- a/src/MongODM.Core/Domain/Models/DbMigrationOperation.cs +++ b/src/MongODM.Core/Domain/Models/DbMigrationOperation.cs @@ -27,6 +27,7 @@ public enum Status New, Running, Completed, + Failed, Cancelled } @@ -64,7 +65,8 @@ public virtual void AddLog(MigrationLogBase log) [PropertyAlterer(nameof(CurrentStatus))] public virtual void TaskCancelled() { - if (CurrentStatus == Status.Completed) + if (CurrentStatus == Status.Completed || + CurrentStatus == Status.Failed) throw new InvalidOperationException(); CurrentStatus = Status.Cancelled; @@ -81,6 +83,16 @@ public virtual void TaskCompleted() CurrentStatus = Status.Completed; } + [PropertyAlterer(nameof(CurrentStatus))] + public virtual void TaskFailed() + { + if (CurrentStatus == Status.Completed || + CurrentStatus == Status.Cancelled) + throw new InvalidOperationException(); + + CurrentStatus = Status.Failed; + } + [PropertyAlterer(nameof(CurrentStatus))] [PropertyAlterer(nameof(TaskId))] public virtual void TaskStarted(string taskId) diff --git a/src/MongODM.Core/Migration/DocumentMigration.cs b/src/MongODM.Core/Migration/DocumentMigration.cs index b13ba900..08ba1b5c 100644 --- a/src/MongODM.Core/Migration/DocumentMigration.cs +++ b/src/MongODM.Core/Migration/DocumentMigration.cs @@ -82,38 +82,45 @@ public override Task MigrateAsync( CancellationToken cancellationToken = default) => _sourceRepository.AccessToCollectionAsync(async sourceCollection => { - if (callbackEveryTotDocuments < 0) - throw new ArgumentOutOfRangeException(nameof(callbackEveryTotDocuments), "Value can't be negative"); - - // Migrate documents. var totMigratedDocuments = 0L; - await sourceCollection.Find(FilterDefinition.Empty, new FindOptions { NoCursorTimeout = true }) - .ForEachAsync(async model => - { - var destinationRepository = destinationRepositorySelector(model); - - // Verify if needs to skip this model. - if (destinationRepository is null) - return; - - // Replace if it's the same collection, insert one otherwise. - if (SourceRepository == destinationRepository) - await destinationRepository.ReplaceAsync(model, updateDependentDocuments: false).ConfigureAwait(false); - else - await destinationRepository.CreateAsync(modelConverter(model)).ConfigureAwait(false); - - // Increment counter. - totMigratedDocuments++; - - // Execute callback. - if (callbackEveryTotDocuments > 0 && - totMigratedDocuments % callbackEveryTotDocuments == 0 && - callbackAsync != null) - await callbackAsync(totMigratedDocuments).ConfigureAwait(false); - - }, cancellationToken).ConfigureAwait(false); - - return MigrationResult.Succeeded(totMigratedDocuments); + try + { + if (callbackEveryTotDocuments < 0) + throw new ArgumentOutOfRangeException(nameof(callbackEveryTotDocuments), "Value can't be negative"); + + // Migrate documents. + await sourceCollection.Find(FilterDefinition.Empty, new FindOptions { NoCursorTimeout = true }) + .ForEachAsync(async model => + { + var destinationRepository = destinationRepositorySelector(model); + + // Verify if needs to skip this model. + if (destinationRepository is null) + return; + + // Replace if it's the same collection, insert one otherwise. + if (SourceRepository == destinationRepository) + await destinationRepository.ReplaceAsync(model, updateDependentDocuments: false).ConfigureAwait(false); + else + await destinationRepository.CreateAsync(modelConverter(model)).ConfigureAwait(false); + + // Increment counter. + totMigratedDocuments++; + + // Execute callback. + if (callbackEveryTotDocuments > 0 && + totMigratedDocuments % callbackEveryTotDocuments == 0 && + callbackAsync != null) + await callbackAsync(totMigratedDocuments).ConfigureAwait(false); + + }, cancellationToken).ConfigureAwait(false); + + return MigrationResult.Succeeded(totMigratedDocuments); + } + catch (Exception e) + { + return MigrationResult.Failed(totMigratedDocuments, e); + } }); } } diff --git a/src/MongODM.Core/Migration/MigrationResult.cs b/src/MongODM.Core/Migration/MigrationResult.cs index 962b135f..9ab0c7fb 100644 --- a/src/MongODM.Core/Migration/MigrationResult.cs +++ b/src/MongODM.Core/Migration/MigrationResult.cs @@ -12,6 +12,8 @@ // See the License for the specific language governing permissions and // limitations under the License. +using System; + namespace Etherna.MongODM.Core.Migration { public class MigrationResult @@ -20,21 +22,24 @@ public class MigrationResult private MigrationResult() { } // Properties. - public bool Succeded { get; private set; } + public Exception? Exception { get; private set; } public long MigratedDocuments { get; private set; } + public bool Succeded { get; private set; } // Methods. - public static MigrationResult Failed() => + public static MigrationResult Failed(long migratedDocuments, Exception? e = null) => new() { + Exception = e, + MigratedDocuments = migratedDocuments, Succeded = false }; public static MigrationResult Succeeded(long migratedDocuments) => new() { - Succeded = true, - MigratedDocuments = migratedDocuments + MigratedDocuments = migratedDocuments, + Succeded = true }; } } \ No newline at end of file diff --git a/src/MongODM.Core/Tasks/MigrateDbContextTask.cs b/src/MongODM.Core/Tasks/MigrateDbContextTask.cs index 6d1636c0..14e3e707 100644 --- a/src/MongODM.Core/Tasks/MigrateDbContextTask.cs +++ b/src/MongODM.Core/Tasks/MigrateDbContextTask.cs @@ -37,6 +37,7 @@ public async Task RunAsync(string dbMigrationOpId, string taskId) { var dbContext = (TDbContext)serviceProvider.GetService(typeof(TDbContext)); var dbMigrationOp = (DbMigrationOperation)await dbContext.DbOperations.FindOneAsync(dbMigrationOpId).ConfigureAwait(false); + var completedWithErrors = false; // Start migrate operation. dbMigrationOp.TaskStarted(taskId); @@ -57,6 +58,9 @@ public async Task RunAsync(string dbMigrationOpId, string taskId) await dbContext.SaveChangesAsync().ConfigureAwait(false); }).ConfigureAwait(false); + if (!result.Succeded) + completedWithErrors = true; + //ended document migration log dbMigrationOp.AddLog(new DocumentMigrationLog( docMigration.SourceRepository.Name, @@ -76,16 +80,32 @@ public async Task RunAsync(string dbMigrationOpId, string taskId) MigrationLogBase.ExecutionState.Executing)); await dbContext.SaveChangesAsync().ConfigureAwait(false); - await repository.BuildIndexesAsync().ConfigureAwait(false); + try + { + await repository.BuildIndexesAsync().ConfigureAwait(false); + + dbMigrationOp.AddLog(new IndexMigrationLog( + repository.Name, + MigrationLogBase.ExecutionState.Succeded)); + } + catch (Exception) + { + completedWithErrors = true; + + dbMigrationOp.AddLog(new IndexMigrationLog( + repository.Name, + MigrationLogBase.ExecutionState.Failed)); + } - dbMigrationOp.AddLog(new IndexMigrationLog( - repository.Name, - MigrationLogBase.ExecutionState.Succeded)); await dbContext.SaveChangesAsync().ConfigureAwait(false); } // Complete task. - dbMigrationOp.TaskCompleted(); + if (!completedWithErrors) + dbMigrationOp.TaskCompleted(); + else + dbMigrationOp.TaskFailed(); + await dbContext.SaveChangesAsync().ConfigureAwait(false); } } From 5bdce313fc263540c1c1e0a80a761972897fd488 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Thu, 16 Jun 2022 01:17:36 +0200 Subject: [PATCH 77/78] fix issue building indexes with secondary model maps --- src/MongODM.Core/Repositories/CollectionRepository.cs | 2 +- .../Serialization/Mapping/ISchemaRegistry.cs | 3 ++- .../Serialization/Mapping/MemberDependency.cs | 7 +++++++ src/MongODM.Core/Serialization/Mapping/SchemaRegistry.cs | 9 ++++++--- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/MongODM.Core/Repositories/CollectionRepository.cs b/src/MongODM.Core/Repositories/CollectionRepository.cs index b5361a6c..166ef2e2 100644 --- a/src/MongODM.Core/Repositories/CollectionRepository.cs +++ b/src/MongODM.Core/Repositories/CollectionRepository.cs @@ -102,7 +102,7 @@ public override Task BuildIndexesAsync(CancellationToken cancellationToken = def })); //referenced documents - var dependencies = DbContext.SchemaRegistry.GetIdMemberDependenciesFromRootModel(typeof(TModel)); + var dependencies = DbContext.SchemaRegistry.GetIdMemberDependenciesFromRootModel(typeof(TModel), true); var idPaths = dependencies .Select(dependency => dependency.MemberPathToString()) diff --git a/src/MongODM.Core/Serialization/Mapping/ISchemaRegistry.cs b/src/MongODM.Core/Serialization/Mapping/ISchemaRegistry.cs index 9ab1ace3..1d86eb9f 100644 --- a/src/MongODM.Core/Serialization/Mapping/ISchemaRegistry.cs +++ b/src/MongODM.Core/Serialization/Mapping/ISchemaRegistry.cs @@ -85,8 +85,9 @@ IModelMapsSchemaBuilder AddModelMapsSchema( /// Get all id member dependencies from a root model type /// /// The model type + /// If true, ignore secondary model maps /// The list of member dependencies - IEnumerable GetIdMemberDependenciesFromRootModel(Type modelType); + IEnumerable GetIdMemberDependenciesFromRootModel(Type modelType, bool onlyFromActiveModelMap = false); /// /// Get all member dependencies that points to a specific member definition diff --git a/src/MongODM.Core/Serialization/Mapping/MemberDependency.cs b/src/MongODM.Core/Serialization/Mapping/MemberDependency.cs index f18bdbc2..94c4a901 100644 --- a/src/MongODM.Core/Serialization/Mapping/MemberDependency.cs +++ b/src/MongODM.Core/Serialization/Mapping/MemberDependency.cs @@ -32,6 +32,7 @@ public class MemberDependency // Constructors. public MemberDependency( IModelMap rootModelMap, + bool rootModelMapIsActive, IEnumerable memberPath, bool useCascadeDelete) { @@ -39,6 +40,7 @@ public MemberDependency( if (!memberPath.Any()) throw new ArgumentException("Member path can't be empty", nameof(memberPath)); RootModelMap = rootModelMap ?? throw new ArgumentNullException(nameof(rootModelMap)); + RootModelMapIsActive = rootModelMapIsActive; UseCascadeDelete = useCascadeDelete; } @@ -119,6 +121,11 @@ public IEnumerable MemberPathToLastEntityModelId /// public IModelMap RootModelMap { get; } + /// + /// True if root model map is the currently active in schema + /// + public bool RootModelMapIsActive { get; } + /// /// True if requested to apply cascade delete /// diff --git a/src/MongODM.Core/Serialization/Mapping/SchemaRegistry.cs b/src/MongODM.Core/Serialization/Mapping/SchemaRegistry.cs index 88eb12af..b9c488cd 100644 --- a/src/MongODM.Core/Serialization/Mapping/SchemaRegistry.cs +++ b/src/MongODM.Core/Serialization/Mapping/SchemaRegistry.cs @@ -143,12 +143,12 @@ public BsonElement GetActiveModelMapIdBsonElement(Type modelType) return activeModelMapIdBsonElement[modelType]; } - public IEnumerable GetIdMemberDependenciesFromRootModel(Type modelType) + public IEnumerable GetIdMemberDependenciesFromRootModel(Type modelType, bool onlyFromActiveModelMap = false) { Freeze(); //needed for initialization if (modelTypeToReferencedIdMemberMapsDictionary.TryGetValue(modelType, out List dependencies)) - return dependencies; + return dependencies.Where(d => !onlyFromActiveModelMap || d.RootModelMapIsActive); return Array.Empty(); } @@ -244,6 +244,7 @@ protected override void FreezeAction() foreach (var modelMap in schema.AllMapsDictionary.Values) CompileDependencyRegisters( modelMap, + modelMap == schema.ActiveMap, modelMap.BsonClassMap, default, Array.Empty()); @@ -267,6 +268,7 @@ protected override void FreezeAction() // Helpers. private void CompileDependencyRegisters( IModelMap modelMap, + bool modelMapIsActive, BsonClassMap currentClassMap, BsonClassMap? lastEntityClassMap, IEnumerable ownedBsonMemberPath, @@ -292,6 +294,7 @@ private void CompileDependencyRegisters( // Identify current member with its root model map, the path from current model map, and cascade delete information. var memberDependency = new MemberDependency( modelMap, + modelMapIsActive, currentMemberPath, useCascadeDeleteSetting ?? false); @@ -332,7 +335,7 @@ private void CompileDependencyRegisters( { bool? useCascadeDelete = (memberSerializer as IReferenceContainerSerializer)?.UseCascadeDelete; foreach (var childClassMap in schemaSerializer.AllChildClassMaps) - CompileDependencyRegisters(modelMap, childClassMap, lastEntityClassMap, currentMemberPath, useCascadeDelete); + CompileDependencyRegisters(modelMap, modelMapIsActive, childClassMap, lastEntityClassMap, currentMemberPath, useCascadeDelete); } } } From 779abe9a7f2bc4f29df0fc4a9f1b55f23d8df5e5 Mon Sep 17 00:00:00 2001 From: Mirko Da Corte Date: Thu, 16 Jun 2022 01:50:09 +0200 Subject: [PATCH 78/78] add license headers --- .../Extensions/ApplicationBuilderExtensions.cs | 16 +++++++++++++++- .../Exceptions/MongodmDbSeedingException.cs | 16 +++++++++++++++- .../Exceptions/MongodmIndexBuildingException.cs | 16 +++++++++++++++- src/MongODM.Core/IDbContextBuilder.cs | 16 +++++++++++++++- .../Options/MongODMOptionsBuilder.cs | 16 +++++++++++++++- src/MongODM.Core/Properties/IsExternalInit.cs | 16 +++++++++++++++- .../Repositories/PaginatedEnumerable.cs | 16 +++++++++++++++- .../Mapping/DiscriminatorRegistry.cs | 16 +++++++++++++++- .../Mapping/IDiscriminatorRegistry.cs | 16 +++++++++++++++- .../Providers/ModelMapSerializationProvider.cs | 16 +++++++++++++++- src/MongODM.Core/Tasks/ITaskRunnerBuilder.cs | 16 +++++++++++++++- .../Utility/DbExecutionContextHandler.cs | 16 +++++++++++++++- .../Utility/SerializationContextAccessor.cs | 16 +++++++++++++++- .../Extensions/HangfireGlobalConfigExtension.cs | 16 +++++++++++++++- 14 files changed, 210 insertions(+), 14 deletions(-) diff --git a/src/MongODM.AspNetCore/Extensions/ApplicationBuilderExtensions.cs b/src/MongODM.AspNetCore/Extensions/ApplicationBuilderExtensions.cs index 88e55007..1eb2214f 100644 --- a/src/MongODM.AspNetCore/Extensions/ApplicationBuilderExtensions.cs +++ b/src/MongODM.AspNetCore/Extensions/ApplicationBuilderExtensions.cs @@ -1,4 +1,18 @@ -using Etherna.ExecContext.AsyncLocal; +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Etherna.ExecContext.AsyncLocal; using Etherna.MongODM.Core; using Etherna.MongODM.Core.Options; using Microsoft.AspNetCore.Builder; diff --git a/src/MongODM.Core/Exceptions/MongodmDbSeedingException.cs b/src/MongODM.Core/Exceptions/MongodmDbSeedingException.cs index c9d0a045..020a132f 100644 --- a/src/MongODM.Core/Exceptions/MongodmDbSeedingException.cs +++ b/src/MongODM.Core/Exceptions/MongodmDbSeedingException.cs @@ -1,4 +1,18 @@ -using System; +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; namespace Etherna.MongODM.Core.Exceptions { diff --git a/src/MongODM.Core/Exceptions/MongodmIndexBuildingException.cs b/src/MongODM.Core/Exceptions/MongodmIndexBuildingException.cs index f57f5c47..2cecc519 100644 --- a/src/MongODM.Core/Exceptions/MongodmIndexBuildingException.cs +++ b/src/MongODM.Core/Exceptions/MongodmIndexBuildingException.cs @@ -1,4 +1,18 @@ -using System; +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; namespace Etherna.MongODM.Core.Exceptions { diff --git a/src/MongODM.Core/IDbContextBuilder.cs b/src/MongODM.Core/IDbContextBuilder.cs index fef5fb24..1dcdaa7d 100644 --- a/src/MongODM.Core/IDbContextBuilder.cs +++ b/src/MongODM.Core/IDbContextBuilder.cs @@ -1,4 +1,18 @@ -using Etherna.MongoDB.Driver; +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Etherna.MongoDB.Driver; using Etherna.MongODM.Core.Options; using System.Collections.Generic; diff --git a/src/MongODM.Core/Options/MongODMOptionsBuilder.cs b/src/MongODM.Core/Options/MongODMOptionsBuilder.cs index 91167983..94a23358 100644 --- a/src/MongODM.Core/Options/MongODMOptionsBuilder.cs +++ b/src/MongODM.Core/Options/MongODMOptionsBuilder.cs @@ -1,4 +1,18 @@ -using System; +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System; using System.Collections.Generic; namespace Etherna.MongODM.Core.Options diff --git a/src/MongODM.Core/Properties/IsExternalInit.cs b/src/MongODM.Core/Properties/IsExternalInit.cs index d3603fa5..252ec65e 100644 --- a/src/MongODM.Core/Properties/IsExternalInit.cs +++ b/src/MongODM.Core/Properties/IsExternalInit.cs @@ -1,4 +1,18 @@ -// Required because of this https://developercommunity.visualstudio.com/t/error-cs0518-predefined-type-systemruntimecompiler/1244809 +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Required because of this https://developercommunity.visualstudio.com/t/error-cs0518-predefined-type-systemruntimecompiler/1244809 namespace System.Runtime.CompilerServices { internal static class IsExternalInit { } diff --git a/src/MongODM.Core/Repositories/PaginatedEnumerable.cs b/src/MongODM.Core/Repositories/PaginatedEnumerable.cs index 6f2c9a09..d2f45986 100644 --- a/src/MongODM.Core/Repositories/PaginatedEnumerable.cs +++ b/src/MongODM.Core/Repositories/PaginatedEnumerable.cs @@ -1,4 +1,18 @@ -using System.Collections.Generic; +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using System.Collections.Generic; namespace Etherna.MongODM.Core.Repositories { diff --git a/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegistry.cs b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegistry.cs index c0c4114e..49ec517c 100644 --- a/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegistry.cs +++ b/src/MongODM.Core/Serialization/Mapping/DiscriminatorRegistry.cs @@ -1,4 +1,18 @@ -using Etherna.MongoDB.Bson; +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Etherna.MongoDB.Bson; using Etherna.MongoDB.Bson.Serialization.Conventions; using Etherna.MongODM.Core.Conventions; using System; diff --git a/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegistry.cs b/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegistry.cs index eb77e408..a0ee2e1b 100644 --- a/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegistry.cs +++ b/src/MongODM.Core/Serialization/Mapping/IDiscriminatorRegistry.cs @@ -1,4 +1,18 @@ -using Etherna.MongoDB.Bson; +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Etherna.MongoDB.Bson; using Etherna.MongoDB.Bson.Serialization.Conventions; using System; diff --git a/src/MongODM.Core/Serialization/Providers/ModelMapSerializationProvider.cs b/src/MongODM.Core/Serialization/Providers/ModelMapSerializationProvider.cs index b17e2a6b..5fa0cc2a 100644 --- a/src/MongODM.Core/Serialization/Providers/ModelMapSerializationProvider.cs +++ b/src/MongODM.Core/Serialization/Providers/ModelMapSerializationProvider.cs @@ -1,4 +1,18 @@ -using Etherna.MongoDB.Bson; +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Etherna.MongoDB.Bson; using Etherna.MongoDB.Bson.Serialization; using Etherna.MongODM.Core.Serialization.Serializers; using System; diff --git a/src/MongODM.Core/Tasks/ITaskRunnerBuilder.cs b/src/MongODM.Core/Tasks/ITaskRunnerBuilder.cs index a7d64bb6..45a32c11 100644 --- a/src/MongODM.Core/Tasks/ITaskRunnerBuilder.cs +++ b/src/MongODM.Core/Tasks/ITaskRunnerBuilder.cs @@ -1,4 +1,18 @@ -using Etherna.MongODM.Core.Options; +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Etherna.MongODM.Core.Options; namespace Etherna.MongODM.Core.Tasks { diff --git a/src/MongODM.Core/Utility/DbExecutionContextHandler.cs b/src/MongODM.Core/Utility/DbExecutionContextHandler.cs index 242d48fd..2eba35b5 100644 --- a/src/MongODM.Core/Utility/DbExecutionContextHandler.cs +++ b/src/MongODM.Core/Utility/DbExecutionContextHandler.cs @@ -1,4 +1,18 @@ -using Etherna.ExecContext; +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Etherna.ExecContext; using Etherna.ExecContext.AsyncLocal; using System; using System.Collections; diff --git a/src/MongODM.Core/Utility/SerializationContextAccessor.cs b/src/MongODM.Core/Utility/SerializationContextAccessor.cs index 4bda1f2b..4adf0697 100644 --- a/src/MongODM.Core/Utility/SerializationContextAccessor.cs +++ b/src/MongODM.Core/Utility/SerializationContextAccessor.cs @@ -1,4 +1,18 @@ -using Etherna.ExecContext; +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Etherna.ExecContext; using Etherna.MongoDB.Bson.Serialization; namespace Etherna.MongODM.Core.Utility diff --git a/src/MongODM.Hangfire/Extensions/HangfireGlobalConfigExtension.cs b/src/MongODM.Hangfire/Extensions/HangfireGlobalConfigExtension.cs index 7a88ce78..a527a5e1 100644 --- a/src/MongODM.Hangfire/Extensions/HangfireGlobalConfigExtension.cs +++ b/src/MongODM.Hangfire/Extensions/HangfireGlobalConfigExtension.cs @@ -1,4 +1,18 @@ -using Etherna.ExecContext.AsyncLocal; +// Copyright 2020-present Etherna Sagl +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +using Etherna.ExecContext.AsyncLocal; using Etherna.MongODM.HF.Filters; namespace Hangfire