/// <summary> /// Gets or sets the <see typeparamref="TFieldType"/> with the specified context. /// </summary> /// <value> /// The <see typeparamref="TFieldType"/>. /// </value> /// <param name="context">The context.</param> /// <returns></returns> public TFieldType this[IAdviceContextTarget context] { get { var introducedField = GetIntroducedField(context.TargetType, context.TargetName); return((TFieldType)introducedField.GetValue(context.Target)); } set { var introducedField = GetIntroducedField(context.TargetType, context.TargetName); introducedField.SetValue(context.Target, value); } }
/// <summary> /// Gets the introduced field. /// Since the attribute may be at assembly level, the advised type is given as parameter /// A cache is kept, by target type. /// </summary> /// <param name="context">The context.</param> /// <returns></returns> protected FieldInfo GetIntroducedField(IAdviceContextTarget context) { var targetType = context.TargetType; // this is where the advice is applied (method, property, event). For shared events this is instance-wide, so unrelated to any target var targetName = IsShared ? null : context.TargetName; var fieldInfos = GetIntroducedFieldsRegistry(context); lock (fieldInfos) { //var key = Tuple.Create(targetType, targetName); var key = new IntroducedFieldsRegistry.Key(_ownerAdvice.GetType(), _ownerMemberInfo, targetName); if (fieldInfos.Fields.TryGetValue(key, out var introducedField)) { return(introducedField); } fieldInfos.Fields[key] = introducedField = Invocation.FindIntroducedField(_ownerAdvice, _ownerMemberInfo, targetType, targetName); return(introducedField); } }
/// <summary> /// Gets the field infos registry. It is shared per instance because of shared introduced fields /// </summary> /// <param name="context">The context.</param> /// <returns></returns> #pragma warning disable 618 private IntroducedFieldsRegistry GetIntroducedFieldsRegistry(IAdviceContextTarget context) { var contextTargetType = context.TargetType; var registryField = GetRegistryField(contextTargetType); var registry = (IntroducedFieldsRegistry)registryField.GetValue(context.Target); if (registry is null) { lock (FieldInfosLock) { registry = (IntroducedFieldsRegistry)registryField.GetValue(context.Target); if (registry is null) { registry = new IntroducedFieldsRegistry(); registryField.SetValue(context.Target, registry); } } } return(registry); }