-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathProjectorMetadata.cs
More file actions
81 lines (64 loc) · 3.02 KB
/
ProjectorMetadata.cs
File metadata and controls
81 lines (64 loc) · 3.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Copyright (c) TotalSoft.
// This source code is licensed under the MIT license.
using System;
using System.Linq;
using System.Reflection;
namespace NBB.ProjectR
{
public interface ISubscribeToMarker { }
public interface ISubscribeTo<T1> : ISubscribeToMarker { }
public interface ISubscribeTo<T1, T2> : ISubscribeToMarker { }
public interface ISubscribeTo<T1, T2, T3> : ISubscribeToMarker { }
public interface ISubscribeTo<T1, T2, T3, T4> : ISubscribeToMarker { }
public interface ISubscribeTo<T1, T2, T3, T4, T5> : ISubscribeToMarker { }
public interface ISubscribeTo<T1, T2, T3, T4, T5, T6> : ISubscribeToMarker { }
public interface ISubscribeTo<T1, T2, T3, T4, T5, T6, T7> : ISubscribeToMarker { }
public interface ISubscribeTo<T1, T2, T3, T4, T5, T6, T7, T8> : ISubscribeToMarker { }
[AttributeUsage(AttributeTargets.Class |
AttributeTargets.Struct)
]
public class SnapshotFrequencyAttribute : System.Attribute
{
public int Frequency { get; }
public SnapshotFrequencyAttribute(int frequency)
{
Frequency = frequency;
}
}
public record ProjectorMetadata(Type ProjectorType, Type ModelType, Type MessageType, Type IdentityType, Type[] SubscriptionTypes, int SnapshotFrequency);
public class ProjectorMetadataAccessor
{
private readonly ProjectorMetadata[] _metadata;
public ProjectorMetadataAccessor(ProjectorMetadata[] metadata)
{
this._metadata = metadata;
}
public ProjectorMetadata GetMetadataFor<TModel>()
=> _metadata.FirstOrDefault(m => m.ModelType == typeof(TModel));
}
public static class ProjectorMetadataService
{
public static ProjectorMetadata[] ScanProjectorsMetadata(
params Assembly[] assemblies)
=> assemblies
.SelectMany(a => a.GetTypes())
.SelectMany(projectorType =>
projectorType.GetInterfaces()
.Where(i => i.IsGenericType && typeof(IProjectorMarker).IsAssignableFrom(i))
.Select(i => i.GetGenericArguments()).Select(args => (ModelType: args[0], MessageType: args[1], IdentityType:args[2]))
.Select(x => new ProjectorMetadata(projectorType, x.ModelType, x.MessageType, x.IdentityType, GetSubscriptionTypes(projectorType), GetSnapshotFrequency(projectorType))))
.ToArray();
private static Type[] GetSubscriptionTypes(Type projectorType)
{
var types =
projectorType.GetInterfaces()
.Where(i => i.IsGenericType && typeof(ISubscribeToMarker).IsAssignableFrom(i))
.SelectMany(i => i.GetGenericArguments())
.Distinct()
.ToArray();
return types;
}
private static int GetSnapshotFrequency(Type projectorType) =>
projectorType.GetCustomAttribute<SnapshotFrequencyAttribute>()?.Frequency ?? 0;
}
}