diff --git a/src/SIL.Harmony/Adapters/CustomAdapterProvider.cs b/src/SIL.Harmony/Adapters/CustomAdapterProvider.cs index 00b723eb..cbcbe64d 100644 --- a/src/SIL.Harmony/Adapters/CustomAdapterProvider.cs +++ b/src/SIL.Harmony/Adapters/CustomAdapterProvider.cs @@ -18,7 +18,7 @@ public CustomAdapterProvider(ObjectTypeListBuilder objectTypeListBuilder) _objectTypeListBuilder = objectTypeListBuilder; JsonTypes.AddDerivedType(typeof(IObjectBase), typeof(TCustomAdapter), TCustomAdapter.TypeName); } - + public CustomAdapterProvider AddWithCustomPolymorphicMapping(string typeName, Action>? configureEntry = null ) where T : class, TCommonInterface @@ -28,7 +28,8 @@ public CustomAdapterProvider AddWithCustomPoly } public CustomAdapterProvider Add( - Action>? configureEntry = null + Action>? configureEntry = null, + Action? jsonTypeModifier = null ) where T : class, TCommonInterface { _objectTypeListBuilder.CheckFrozen(); @@ -39,7 +40,7 @@ public CustomAdapterProvider Add( var entity = builder.Entity(); configureEntry?.Invoke(entity); return entity; - }) + }, jsonTypeModifier) ); return this; } @@ -69,4 +70,4 @@ public interface ICustomAdapter : IObjectBase, IPolyTyp public static abstract TSelf Create(TCommonInterface obj); static string IPolyType.TypeName => TSelf.AdapterTypeName; public static abstract string AdapterTypeName { get; } -} \ No newline at end of file +} diff --git a/src/SIL.Harmony/Adapters/IObjectAdapterProvider.cs b/src/SIL.Harmony/Adapters/IObjectAdapterProvider.cs index 712223d8..7e993f31 100644 --- a/src/SIL.Harmony/Adapters/IObjectAdapterProvider.cs +++ b/src/SIL.Harmony/Adapters/IObjectAdapterProvider.cs @@ -1,13 +1,14 @@ +using System.Text.Json.Serialization.Metadata; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Metadata.Builders; namespace SIL.Harmony.Adapters; -internal record AdapterRegistration(Type ObjectDbType, Func EntityBuilder); +internal record AdapterRegistration(Type ObjectDbType, Func EntityBuilder, Action? JsonTypeModifier = null); internal interface IObjectAdapterProvider { IEnumerable GetRegistrations(); IObjectBase Adapt(object obj); bool CanAdapt(object obj); -} \ No newline at end of file +} diff --git a/src/SIL.Harmony/CrdtConfig.cs b/src/SIL.Harmony/CrdtConfig.cs index 2ae08959..c96aa4df 100644 --- a/src/SIL.Harmony/CrdtConfig.cs +++ b/src/SIL.Harmony/CrdtConfig.cs @@ -69,6 +69,12 @@ private void JsonTypeModifier(JsonTypeInfo typeInfo) typeInfo.PolymorphismOptions!.DerivedTypes.Add(type); } } + + var registration = ObjectTypeListBuilder.RegistrationsByType.GetValueOrDefault(typeInfo.Type); + if (registration?.JsonTypeModifier is not null && registration.ObjectDbType == typeInfo.Type) + { + registration.JsonTypeModifier(typeInfo); + } } public bool RemoteResourcesEnabled { get; private set; } @@ -131,6 +137,7 @@ public void Freeze() { if (_frozen) return; _frozen = true; + _frozenRegistrationsByType = RegistrationsByType; foreach (var registration in AdapterProviders.SelectMany(a => a.GetRegistrations())) { ModelConfigurations.Add((builder, config) => @@ -156,6 +163,10 @@ internal void CheckFrozen() internal List AdapterProviders { get; } = []; + private IReadOnlyDictionary? _frozenRegistrationsByType; + internal IReadOnlyDictionary RegistrationsByType + => _frozenRegistrationsByType ?? AdapterProviders.SelectMany(p => p.GetRegistrations()).ToDictionary(r => r.ObjectDbType); + public DefaultAdapterProvider DefaultAdapter() { CheckFrozen(); @@ -164,7 +175,7 @@ public DefaultAdapterProvider DefaultAdapter() AdapterProviders.Add(adapter); return adapter; } - + /// /// add a custom adapter for a common interface /// this is required as CRDT objects must express their references and have an Id property