CSLA.NET 5.4.2
CSLA .NET is a software development framework that helps you build a reusable, maintainable object-oriented business layer for your app.
PropertyInfoManager.cs
Go to the documentation of this file.
1//-----------------------------------------------------------------------
2// <copyright file="PropertyInfoManager.cs" company="Marimer LLC">
3// Copyright (c) Marimer LLC. All rights reserved.
4// Website: https://cslanet.com
5// </copyright>
6// <summary>Indicates that the specified property belongs</summary>
7//-----------------------------------------------------------------------
8using System;
9using System.Collections.Generic;
10using Csla.Properties;
11using System.Linq;
12using Csla.Reflection;
13
15{
19 internal class PropertyComparer : Comparer<IPropertyInfo>
20 {
21 public override int Compare(IPropertyInfo x, IPropertyInfo y)
22 {
23 return StringComparer.InvariantCulture.Compare(x.Name, y.Name);
24 }
25 }
26
30 public static class PropertyInfoManager
31 {
32 private static object _cacheLock = new object();
33 private static Dictionary<Type, PropertyInfoList> _propertyInfoCache;
34
35 private static Dictionary<Type, PropertyInfoList> PropertyInfoCache
36 {
37 get
38 {
39 if (_propertyInfoCache == null)
40 {
41 lock (_cacheLock)
42 {
43 if (_propertyInfoCache == null)
44 _propertyInfoCache = new Dictionary<Type, PropertyInfoList>();
45 }
46 }
47 return _propertyInfoCache;
48 }
49 }
50
51 internal static PropertyInfoList GetPropertyListCache(Type objectType)
52 {
53 var cache = PropertyInfoCache;
54 var found = cache.TryGetValue(objectType, out PropertyInfoList list);
55 if (!found)
56 {
57 lock (cache)
58 {
59 found = cache.TryGetValue(objectType, out list);
60 if (!found)
61 {
62 list = new PropertyInfoList();
63 cache.Add(objectType, list);
64 FieldDataManager.ForceStaticFieldInit(objectType);
65 }
66 }
67 }
68 return list;
69 }
70
87 internal static PropertyInfo<T> RegisterProperty<T>(Type objectType, PropertyInfo<T> info)
88 {
89 var list = GetPropertyListCache(objectType);
90 lock (list)
91 {
92 if (list.IsLocked)
93 throw new InvalidOperationException(string.Format(Resources.PropertyRegisterNotAllowed, info.Name, objectType.Name));
94
95 // This is the semantic code for RegisterProperty
96 //if (list.Any(pi => pi.Name == info.Name))
97 // throw new InvalidOperationException(string.Format(Resources.PropertyRegisterDuplicateNotAllowed, info.Name));
98 //list.Add(info);
99 //list.Sort();
100
101 // Optimized code
102 // BinarySearch uses the same comparer as list.Sort() to find the item in a sorted list.
103 // If not found then returns the negative index for item in sorted list (to insert).
104 // This allows us to insert the item right away with no need for explicit Sort on the list.
105 var index = list.BinarySearch(info, new PropertyComparer());
106 // if found then throw DuplicateNotAllowed
107 if (index >= 0)
108 throw new InvalidOperationException(string.Format(Resources.PropertyRegisterDuplicateNotAllowed, info.Name));
109
110 // insert info at correct sorted index
111 list.Insert(~index, info);
112 }
113 return info;
114 }
115
129 public static PropertyInfoList GetRegisteredProperties(Type objectType)
130 {
131 // return a copy of the list to avoid
132 // possible locking issues
133 var list = GetPropertyListCache(objectType);
134 lock (list)
135 return new PropertyInfoList(list);
136 }
137
144 public static IPropertyInfo GetRegisteredProperty(Type objectType, string propertyName)
145 {
146 return GetRegisteredProperties(objectType).FirstOrDefault(p => p.Name == propertyName);
147 }
148 }
149}
A strongly-typed resource class, for looking up localized strings, etc.
static string PropertyRegisterDuplicateNotAllowed
Looks up a localized string similar to Cannot register property {0}, a PropertyInfo with the same nam...
static string PropertyRegisterNotAllowed
Looks up a localized string similar to Cannot register property {0} after containing type ({1}) has b...