Skip to content

Commit 6e26331

Browse files
committed
refactor: introduce more compact syntax for MembersOverrides and MembersTemplates
1 parent e58feda commit 6e26331

26 files changed

+230
-197
lines changed

sources/RevitDBExplorer/Domain/DataModel/Members/Base/DeclaringType.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@ internal class DeclaringType: IEquatable<DeclaringType>, IComparable<DeclaringTy
1616
public DocXml Documentation => documentation?.Value ?? DocXml.Empty;
1717

1818

19-
private DeclaringType(string name, int level, Func<DocXml> documentationFactoryMethod = null)
19+
private DeclaringType(string name, int inheritanceLevel, Func<DocXml> documentationFactoryMethod = null)
2020
{
2121
Name = name;
22-
InheritanceLevel = level;
22+
InheritanceLevel = inheritanceLevel;
2323
if (documentationFactoryMethod != null)
2424
{
2525
documentation = new Lazy<DocXml>(documentationFactoryMethod);

sources/RevitDBExplorer/Domain/DataModel/Members/Base/MemberKind.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,5 +2,13 @@
22

33
namespace RevitDBExplorer.Domain.DataModel.Members.Base
44
{
5-
internal enum MemberKind { Property, Method, StaticMethod, Extra, AsArgument, None }
5+
internal enum MemberKind
6+
{
7+
Property,
8+
Method,
9+
StaticMethod,
10+
Extra,
11+
AsArgument,
12+
None
13+
}
614
}
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
using System;
2+
using System.Linq.Expressions;
3+
using Autodesk.Revit.DB;
4+
using RevitDBExplorer.Domain.DataModel.Accessors;
5+
using RevitDBExplorer.Domain.DataModel.Members.Accessors;
6+
7+
// (c) Revit Database Explorer https://github.com/NeVeSpl/RevitDBExplorer/blob/main/license.md
8+
9+
namespace RevitDBExplorer.Domain.DataModel.Members.Base
10+
{
11+
internal interface IMemberOverride
12+
{
13+
public string UniqueId { get; }
14+
public Func<IAccessor> MemberAccessorFactory { get; init; }
15+
}
16+
17+
18+
19+
internal class MemberOverride<TForType> : IMemberOverride
20+
{
21+
public string UniqueId { get; init; }
22+
public Func<IAccessor> MemberAccessorFactory { get; init; }
23+
24+
25+
public static IMemberOverride ByFunc<TReturnType>(Expression<Func<Document, TForType, TReturnType>> getter)
26+
{
27+
var compiledGetter = getter.Compile();
28+
var uniqueId = getter.GetUniqueId();
29+
30+
return new MemberOverride<TForType>()
31+
{
32+
UniqueId = uniqueId,
33+
MemberAccessorFactory = () => new MemberAccessorByFunc<TForType, TReturnType>(compiledGetter)
34+
};
35+
}
36+
}
37+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using System;
2+
using System.Linq.Expressions;
3+
using Autodesk.Revit.DB;
4+
using RevitDBExplorer.Domain.DataModel.Accessors;
5+
using RevitDBExplorer.Domain.DataModel.Members.Accessors;
6+
7+
// (c) Revit Database Explorer https://github.com/NeVeSpl/RevitDBExplorer/blob/main/license.md
8+
9+
namespace RevitDBExplorer.Domain.DataModel.Members.Base
10+
{
11+
internal interface ISnoopableMemberTemplate
12+
{
13+
bool CanBeUsedWith(object @object);
14+
MemberDescriptor Descriptor { get; }
15+
}
16+
17+
18+
internal sealed class MemberTemplate<TForType> : ISnoopableMemberTemplate
19+
{
20+
private Func<TForType, bool> CanBeUsedTyped { get; init; }
21+
public MemberDescriptor Descriptor { get; init; }
22+
23+
public bool CanBeUsedWith(object @object)
24+
{
25+
if (CanBeUsedTyped != null)
26+
{
27+
Guard.IsAssignableToType<TForType>(@object);
28+
return CanBeUsedTyped((TForType)@object);
29+
}
30+
return true;
31+
}
32+
33+
34+
public static ISnoopableMemberTemplate Create<TReturnType>(Expression<Func<Document, TForType, TReturnType>> getter, Func<TForType, bool> canBeUsed = null, MemberKind kind = MemberKind.StaticMethod)
35+
{
36+
var compiledGetter = getter.Compile();
37+
var methodCallExpression = getter.Body as MethodCallExpression;
38+
var memberAccessor = new MemberAccessorByFunc<TForType, TReturnType>(compiledGetter);
39+
40+
return Create(methodCallExpression.Method.DeclaringType, methodCallExpression.Method.Name, memberAccessor, canBeUsed, kind, () => RevitDocumentationReader.GetMethodComments(methodCallExpression.Method));
41+
}
42+
public static ISnoopableMemberTemplate Create(Type declaringType, string memberName, IAccessor memberAccessor, Func<TForType, bool> canBeUsed = null, MemberKind kind = MemberKind.StaticMethod, Func<DocXml> documentationFactoryMethod = null)
43+
{
44+
return new MemberTemplate<TForType>()
45+
{
46+
Descriptor = new MemberDescriptor(typeof(TForType), kind, memberName, declaringType, memberAccessor, documentationFactoryMethod),
47+
CanBeUsedTyped = canBeUsed,
48+
};
49+
}
50+
}
51+
}

sources/RevitDBExplorer/Domain/DataModel/Members/MemberAccessorFactory.cs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using System.Reflection;
66
using RevitDBExplorer.Domain.DataModel.Accessors;
77
using RevitDBExplorer.Domain.DataModel.Members.Accessors;
8+
using RevitDBExplorer.Domain.DataModel.Members.Base;
89
using RevitDBExplorer.Domain.DataModel.Members.Internals;
910

1011

@@ -15,7 +16,7 @@ namespace RevitDBExplorer.Domain.DataModel.Members
1516
internal static class MemberAccessorFactory
1617
{
1718
private static readonly Dictionary<string, Func<IAccessor>> memberAccessorOverrides = new();
18-
19+
1920

2021
public static void Init()
2122
{
@@ -32,6 +33,16 @@ static MemberAccessorFactory()
3233
memberAccessorOverrides[memberId] = accessor.GetType().CompileFactoryMethod<IAccessor>();
3334
}
3435
}
36+
37+
var overridesCollections = GetAllInstancesThatImplement<IHaveMembersOverrides>();
38+
39+
foreach (var collection in overridesCollections)
40+
{
41+
foreach (var memberOverride in collection.GetOverrides())
42+
{
43+
memberAccessorOverrides[memberOverride.UniqueId] = memberOverride.MemberAccessorFactory;
44+
}
45+
}
3546
}
3647
private static IEnumerable<T> GetAllInstancesThatImplement<T>() where T : class
3748
{
@@ -46,8 +57,8 @@ private static IEnumerable<T> GetAllInstancesThatImplement<T>() where T : class
4657
public static IAccessor CreateMemberAccessor(MethodInfo getMethod, MethodInfo setMethod)
4758
{
4859
var memberAccessor = CreateMemberAccessor(getMethod);
49-
memberAccessor.UniqueId = getMethod.GetUniqueId();
5060

61+
memberAccessor.UniqueId = getMethod.GetUniqueId();
5162
if (string.IsNullOrEmpty(memberAccessor.DefaultInvocation.Syntax))
5263
{
5364
memberAccessor.DefaultInvocation.Syntax = getMethod.GenerateInvocation();
@@ -61,7 +72,7 @@ private static IAccessor CreateMemberAccessor(MethodInfo getMethod)
6172
if (memberAccessorOverrides.TryGetValue(getMethod.GetUniqueId(), out Func<IAccessor> factory))
6273
{
6374
return factory();
64-
}
75+
}
6576

6677
if (getMethod.IsStatic)
6778
{
@@ -102,6 +113,11 @@ private static IAccessor CreateMemberAccessor(MethodInfo getMethod)
102113

103114
internal interface ICanCreateMemberAccessor
104115
{
105-
IEnumerable<LambdaExpression> GetHandledMembers();
116+
IEnumerable<LambdaExpression> GetHandledMembers();
117+
}
118+
119+
internal interface IHaveMembersOverrides
120+
{
121+
IEnumerable<IMemberOverride> GetOverrides();
106122
}
107123
}

sources/RevitDBExplorer/Domain/DataModel/Members/MemberStreamer.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,14 +33,14 @@ public static IEnumerable<MemberDescriptor> StreamDescriptors(SnoopableContext c
3333
}
3434

3535
var type = snoopableObject.GetType();
36-
var cachableDescriptors = Cache_Descriptors.GetOrCreate(type, _ => StreamDescriptorsForPropsAndMethods(snoopableObject).ToArray());
36+
var cachableDescriptors = Cache_DescriptorsForPropsAndMethods.GetOrCreate(type, _ => StreamDescriptorsForPropsAndMethods(snoopableObject).ToArray());
3737

3838
foreach (var member in cachableDescriptors)
3939
{
4040
yield return member;
4141
}
4242
}
43-
private static readonly Dictionary<Type, IReadOnlyList<MemberDescriptor>> Cache_Descriptors = new();
43+
private static readonly Dictionary<Type, IReadOnlyList<MemberDescriptor>> Cache_DescriptorsForPropsAndMethods = new();
4444

4545
private static IEnumerable<MemberDescriptor> StreamDescriptorsForPropsAndMethods(object snoopableObject)
4646
{

sources/RevitDBExplorer/Domain/DataModel/Members/MemberStreamerForTemplates.cs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using System;
22
using System.Collections.Generic;
33
using System.Linq;
4-
using RevitDBExplorer.Domain.DataModel.MembersTemplates.Base;
54
using RevitDBExplorer.Domain.DataModel.Members.Base;
65

76
// (c) Revit Database Explorer https://github.com/NeVeSpl/RevitDBExplorer/blob/main/license.md
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
using System.Collections.Generic;
2+
using Autodesk.Revit.DB;
3+
using RevitDBExplorer.Domain.DataModel.Members;
4+
using RevitDBExplorer.Domain.DataModel.Members.Base;
5+
6+
// (c) Revit Database Explorer https://github.com/NeVeSpl/RevitDBExplorer/blob/main/license.md
7+
8+
namespace RevitDBExplorer.Domain.DataModel.MembersOverrides
9+
{
10+
internal class Element_Overrides : IHaveMembersOverrides
11+
{
12+
public IEnumerable<IMemberOverride> GetOverrides() =>
13+
[
14+
MemberOverride<Element>.ByFunc((document, element) => element.GetDependentElements(null)),
15+
];
16+
}
17+
}

sources/RevitDBExplorer/Domain/DataModel/MembersOverrides/Element/Element_GetDependentElements.cs

Lines changed: 0 additions & 21 deletions
This file was deleted.

sources/RevitDBExplorer/Domain/DataModel/MembersTemplates/Base/SnoopableMemberTemplate.cs

Lines changed: 0 additions & 51 deletions
This file was deleted.

0 commit comments

Comments
 (0)