Skip to content

Commit 8b1237e

Browse files
committed
allow multiple object adapters
1 parent e767624 commit 8b1237e

File tree

4 files changed

+41
-19
lines changed

4 files changed

+41
-19
lines changed

src/SIL.Harmony/Adapters/CustomAdapterProvider.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,7 @@ public class CustomAdapterProvider<TCommonInterface, TCustomAdapter> : IObjectAd
1212
{
1313
private readonly ObjectTypeListBuilder _objectTypeListBuilder;
1414
private readonly List<AdapterRegistration> _objectTypes = new();
15-
private Dictionary<Type, List<JsonDerivedType>> JsonTypes { get; } = [];
16-
Dictionary<Type, List<JsonDerivedType>> IObjectAdapterProvider.JsonTypes => JsonTypes;
15+
private Dictionary<Type, List<JsonDerivedType>> JsonTypes => _objectTypeListBuilder.JsonTypes;
1716

1817
public CustomAdapterProvider(ObjectTypeListBuilder objectTypeListBuilder)
1918
{
@@ -55,6 +54,11 @@ IObjectBase IObjectAdapterProvider.Adapt(object obj)
5554
{
5655
return TCustomAdapter.Create((TCommonInterface)obj);
5756
}
57+
58+
public bool CanAdapt(object obj)
59+
{
60+
return obj is TCommonInterface;
61+
}
5862
}
5963

6064
// it's possible to implement this without a Common interface

src/SIL.Harmony/Adapters/DefaultAdapterProvider.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ IObjectBase IObjectAdapterProvider.Adapt(object obj)
3838
$"Object is of type {obj.GetType().Name} which does not implement {nameof(IObjectBase)}");
3939
}
4040

41-
private Dictionary<Type, List<JsonDerivedType>> JsonTypes { get; } = [];
42-
Dictionary<Type, List<JsonDerivedType>> IObjectAdapterProvider.JsonTypes => JsonTypes;
41+
public bool CanAdapt(object obj)
42+
{
43+
return obj is IObjectBase;
44+
}
45+
46+
private Dictionary<Type, List<JsonDerivedType>> JsonTypes => objectTypeListBuilder.JsonTypes;
4347
}

src/SIL.Harmony/Adapters/IObjectAdapterProvider.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,5 @@ internal interface IObjectAdapterProvider
1111
{
1212
IEnumerable<AdapterRegistration> GetRegistrations();
1313
IObjectBase Adapt(object obj);
14-
15-
Dictionary<Type, List<JsonDerivedType>> JsonTypes { get; }
14+
bool CanAdapt(object obj);
1615
}

src/SIL.Harmony/CrdtConfig.cs

Lines changed: 28 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,12 @@ public void AddRemoteResourceEntity(string? cachePath = null)
7575
{
7676
RemoteResourcesEnabled = true;
7777
LocalResourceCachePath = cachePath ?? LocalResourceCachePath;
78-
ObjectTypeListBuilder.Add<RemoteResource>();
78+
ObjectTypeListBuilder.DefaultAdapter().Add<RemoteResource>();
7979
ChangeTypeListBuilder.Add<RemoteResourceUploadedChange>();
8080
ChangeTypeListBuilder.Add<CreateRemoteResourceChange>();
8181
ChangeTypeListBuilder.Add<CreateRemoteResourcePendingUploadChange>();
8282
ChangeTypeListBuilder.Add<DeleteChange<RemoteResource>>();
83-
ObjectTypeListBuilder.AddDbModelConfig(builder =>
83+
ObjectTypeListBuilder.ModelConfigurations.Add((builder, config) =>
8484
{
8585
var entity = builder.Entity<LocalResource>();
8686
entity.HasKey(lr => lr.Id);
@@ -127,8 +127,7 @@ public void Freeze()
127127
{
128128
if (_frozen) return;
129129
_frozen = true;
130-
JsonTypes = AdapterProvider.JsonTypes;
131-
foreach (var registration in AdapterProvider.GetRegistrations())
130+
foreach (var registration in AdapterProviders.SelectMany(a => a.GetRegistrations()))
132131
{
133132
ModelConfigurations.Add((builder, config) =>
134133
{
@@ -147,19 +146,18 @@ internal void CheckFrozen()
147146
if (_frozen) throw new InvalidOperationException($"{nameof(ObjectTypeListBuilder)} is frozen");
148147
}
149148

150-
internal Dictionary<Type, List<JsonDerivedType>>? JsonTypes { get; set; }
149+
internal Dictionary<Type, List<JsonDerivedType>> JsonTypes { get; } = [];
151150

152151
internal List<Action<ModelBuilder, CrdtConfig>> ModelConfigurations { get; } = [];
153152

154-
internal IObjectAdapterProvider AdapterProvider => _adapterProvider ?? throw new InvalidOperationException("No adapter has been added to the builder");
155-
private IObjectAdapterProvider? _adapterProvider;
153+
internal List<IObjectAdapterProvider> AdapterProviders { get; } = [];
156154

157155
public DefaultAdapterProvider DefaultAdapter()
158156
{
159157
CheckFrozen();
160-
if (_adapterProvider is not null) throw new InvalidOperationException("adapter has already been added");
161-
var adapter = new DefaultAdapterProvider(this);
162-
_adapterProvider = adapter;
158+
if (AdapterProviders.OfType<DefaultAdapterProvider>().SingleOrDefault() is {} adapter) return adapter;
159+
adapter = new DefaultAdapterProvider(this);
160+
AdapterProviders.Add(adapter);
163161
return adapter;
164162
}
165163

@@ -182,9 +180,26 @@ public CustomAdapterProvider<TCommonInterface, TAdapter> CustomAdapter<TCommonIn
182180
where TCommonInterface : class where TAdapter : class, ICustomAdapter<TAdapter, TCommonInterface>, IPolyType
183181
{
184182
CheckFrozen();
185-
if (_adapterProvider is not null) throw new InvalidOperationException("adapter has already been added");
186-
var adapter = new CustomAdapterProvider<TCommonInterface, TAdapter>(this);
187-
_adapterProvider = adapter;
183+
if (AdapterProviders.OfType<CustomAdapterProvider<TCommonInterface, TAdapter>>().SingleOrDefault() is {} adapter) return adapter;
184+
adapter = new CustomAdapterProvider<TCommonInterface, TAdapter>(this);
185+
AdapterProviders.Add(adapter);
188186
return adapter;
189187
}
188+
189+
internal IObjectBase Adapt(object obj)
190+
{
191+
if (AdapterProviders is [{ } defaultAdapter])
192+
{
193+
return defaultAdapter.Adapt(obj);
194+
}
195+
196+
foreach (var objectAdapterProvider in AdapterProviders)
197+
{
198+
if (objectAdapterProvider.CanAdapt(obj))
199+
{
200+
return objectAdapterProvider.Adapt(obj);
201+
}
202+
}
203+
throw new ArgumentException($"Unable to adapt object of type {obj.GetType()}");
204+
}
190205
}

0 commit comments

Comments
 (0)