自定义属性,例如
CatalogueLazyLoad
基本上是在构建时与属性关联的元数据。不能在运行时修改其字段的值。
还有在运行时为每个属性创建的方面的实例(它也是
Lazyload目录
)。但是这些不能通过反射API和类似
propertyInfo.GetCustomAttribute
.
您需要的是在
Lazyload目录
类。对于这种用例,在目标类中引入和导入自定义属性会很好地工作。我建议你介绍一个房产
LoadedCharsets
进入目标类。此属性将保留已加载的字符集集合,所有方面实例都将访问同一个集合实例。
下面的示例显示如何在
Lazyload目录
类。它不处理多线程,因此如果需要,您可能需要添加多线程。
[PSerializable]
[MulticastAttributeUsage(PersistMetaData = true, AllowExternalAssemblies = false)]
[LinesOfCodeAvoided(50)]
// We need to implement IInstanceScopedAspect to introduce and import members
public sealed class CatalogueLazyLoad : LocationInterceptionAspect, IInstanceScopedAspect
{
public string Name { get; set; }
public string Charset { get; set; }
public CacheType Cache { get; set; }
// Introduce a new property into the target class (only once)
[IntroduceMember(OverrideAction = MemberOverrideAction.Ignore)]
public HashSet<string> LoadedCharsets { get; set; }
// Import the introduced property (it may be introduced by this aspect or another aspect on another property)
[ImportMember("LoadedCharsets", IsRequired = true, Order = ImportMemberOrder.AfterIntroductions)]
public Property<HashSet<string>> LoadedCharsetsProperty;
public CatalogueLazyLoad(string name, string charset)
{
Name = name;
Charset = charset;
Cache = CacheType.CACHED;
}
private void GetValue(LocationInterceptionArgs args, bool propagate = false)
{
var properties = args.Instance.GetType().GetProperties();
// JSONObject is just an object with string KEY and string VALUE, you can add dummy data here using a Dictionary<string, string>
IEnumerable<JSONObject> result = API.Methods.GetCharsetData(id, Charset).Result;
if (result.Count() > 0)
{
foreach (PropertyInfo propertyInfo in properties)
{
CatalogueLazyLoad attribute = propertyInfo.GetCustomAttribute<CatalogueLazyLoad>();
if (attribute != null && attribute.Charset == Charset)
{
propertyInfo.SetValue(args.Instance,
Convert.ChangeType(result.Where(x => x.Key == attribute.Name).Select(x => x.Value).FirstOrDefault(), propertyInfo.PropertyType, CultureInfo.CurrentCulture),
null);
}
}
if (propagate)
{
this.LoadedCharsetsProperty.Get().Add(this.Charset);
}
args.ProceedGetValue();
}
}
public override sealed void OnGetValue(LocationInterceptionArgs args)
{
base.OnGetValue(args);
switch (Cache)
{
case CacheType.CACHED:
bool loaded = this.LoadedCharsetsProperty.Get().Contains(this.Charset);
if (!loaded)
{
GetValue(args, true);
}
break;
case CacheType.FORCE_NO_CACHE:
GetValue(args);
break;
default:
break;
}
}
public object CreateInstance(AdviceArgs adviceArgs)
{
return this.MemberwiseClone();
}
public void RuntimeInitializeInstance()
{
this.LoadedCharsetsProperty.Set(new HashSet<string>());
}
}