Skip to content

Commit 809c74d

Browse files
committed
feat: improve performance through caching
changes: - modified the `NotifiableObject` class - fixed the `NotifyChangedAttributeTests` class - fixed the `NotifyChangingAttributeTests` class closes #114
1 parent ce9b8dd commit 809c74d

File tree

3 files changed

+59
-18
lines changed

3 files changed

+59
-18
lines changed

src/BB84.Notifications/NotifiableObject.cs

+39-14
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,14 @@ namespace BB84.Notifications;
1313
/// </summary>
1414
public abstract class NotifiableObject : INotifiableObject
1515
{
16+
private static readonly Dictionary<string, string[]> PropertyChangedAttributeCache = [];
17+
private static readonly Dictionary<string, string[]> PropertyChangingAttributeCache = [];
18+
19+
/// <summary>
20+
/// Initializes a new instance of the <see cref="NotifiableObject"/> class.
21+
/// </summary>
22+
protected NotifiableObject() => FillCaches();
23+
1624
/// <inheritdoc/>
1725
public event PropertyChangedEventHandler? PropertyChanged;
1826

@@ -79,16 +87,12 @@ protected void RaisePropertyChanging<T>(string propertyName, T value)
7987
/// <param name="propertyName">The name of the calling property.</param>
8088
private void RaiseChangedAttribute(string propertyName)
8189
{
82-
PropertyInfo? propertyInfo = GetType().GetProperty(propertyName);
90+
bool success = PropertyChangedAttributeCache.TryGetValue(propertyName, out string[]? propertiesToNotify);
8391

84-
if (propertyInfo is not null)
92+
if (success && propertiesToNotify is not null)
8593
{
86-
NotifyChangedAttribute? attribute =
87-
propertyInfo.GetCustomAttribute(typeof(NotifyChangedAttribute), false) as NotifyChangedAttribute;
88-
89-
if (attribute is not null)
90-
foreach (string property in attribute.Properties)
91-
RaisePropertyChanged(property);
94+
foreach (string propertyToNotify in propertiesToNotify)
95+
RaisePropertyChanged(propertyToNotify);
9296
}
9397
}
9498

@@ -99,16 +103,37 @@ private void RaiseChangedAttribute(string propertyName)
99103
/// <param name="propertyName">The name of the calling property.</param>
100104
private void RaiseChangingAttribute(string propertyName)
101105
{
102-
PropertyInfo? propertyInfo = GetType().GetProperty(propertyName);
106+
bool success = PropertyChangingAttributeCache.TryGetValue(propertyName, out string[]? propertiesToNotify);
103107

104-
if (propertyInfo is not null)
108+
if (success && propertiesToNotify is not null)
105109
{
106-
NotifyChangingAttribute? attribute =
110+
foreach (string propertyToNotify in propertiesToNotify)
111+
RaisePropertyChanging(propertyToNotify);
112+
}
113+
}
114+
115+
/// <summary>
116+
/// The method fills the <see cref="PropertyChangedAttributeCache"/> and the <see cref="PropertyChangingAttributeCache"/>
117+
/// when the class is instantiated so that it only has to do this once. This means that subsequent calls to
118+
/// <see cref="RaiseChangedAttribute"/> and <see cref="RaiseChangingAttribute"/> no longer have to do this.
119+
/// </summary>
120+
private void FillCaches()
121+
{
122+
PropertyInfo[] propertiesInfos = GetType().GetProperties();
123+
124+
foreach (PropertyInfo propertyInfo in propertiesInfos)
125+
{
126+
NotifyChangedAttribute? changedAttribute =
127+
propertyInfo.GetCustomAttribute(typeof(NotifyChangedAttribute), false) as NotifyChangedAttribute;
128+
129+
if (changedAttribute is not null)
130+
PropertyChangedAttributeCache.Add(propertyInfo.Name, changedAttribute.Properties);
131+
132+
NotifyChangingAttribute? changingAttribute =
107133
propertyInfo.GetCustomAttribute(typeof(NotifyChangingAttribute), false) as NotifyChangingAttribute;
108134

109-
if (attribute is not null)
110-
foreach (string property in attribute.Properties)
111-
RaisePropertyChanging(property);
135+
if (changingAttribute is not null)
136+
PropertyChangingAttributeCache.Add(propertyInfo.Name, changingAttribute.Properties);
112137
}
113138
}
114139
}

tests/BB84.NotificationsTests/Attributes/NotifyChangedAttributeTests.cs

+10-2
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,18 @@ public TestClass(int quantity, int value)
3232
}
3333

3434
[NotifyChanged(nameof(TotalValue))]
35-
public int Quantity { get => _quantity; set => SetProperty(ref _quantity, value); }
35+
public int Quantity
36+
{
37+
get => _quantity;
38+
set => SetProperty(ref _quantity, value);
39+
}
3640

3741
[NotifyChanged(nameof(TotalValue))]
38-
public int Value { get => _value; set => SetProperty(ref _value, value); }
42+
public int Value
43+
{
44+
get => _value;
45+
set => SetProperty(ref _value, value);
46+
}
3947

4048
public int TotalValue => Quantity * Value;
4149
}

tests/BB84.NotificationsTests/Attributes/NotifyChangingAttributeTests.cs

+10-2
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,18 @@ public TestClass(int quantity, int value)
3232
}
3333

3434
[NotifyChanging(nameof(TotalValue))]
35-
public int Quantity { get => _quantity; set => SetProperty(ref _quantity, value); }
35+
public int Quantity
36+
{
37+
get => _quantity;
38+
set => SetProperty(ref _quantity, value);
39+
}
3640

3741
[NotifyChanging(nameof(TotalValue))]
38-
public int Value { get => _value; set => SetProperty(ref _value, value); }
42+
public int Value
43+
{
44+
get => _value;
45+
set => SetProperty(ref _value, value);
46+
}
3947

4048
public int TotalValue => Quantity * Value;
4149
}

0 commit comments

Comments
 (0)