/// <summary> /// Introduces the member. /// </summary> /// <param name="moduleDefinition">The module definition.</param> /// <param name="memberName">Name of the member.</param> /// <param name="memberType">Type of the member.</param> /// <param name="isStatic">if set to <c>true</c> [is static].</param> /// <param name="adviceType">The advice.</param> /// <param name="advisedType">The type definition.</param> /// <param name="markerAttribute">The marker attribute ctor.</param> /// <param name="introducedMemberName">Name of the introduced member.</param> /// <param name="isNotSerialized">if set to <c>true</c> [is not serialized].</param> /// <param name="context">The context.</param> private void IntroduceMember(ModuleDef moduleDefinition, string memberName, ITypeDefOrRef memberType, bool isStatic, ITypeDefOrRef adviceType, TypeDef advisedType, ICustomAttributeType markerAttribute, string introducedMemberName, bool isNotSerialized, WeavingContext context) { if (IsIntroduction(memberType, out var introducedFieldType, out var isShared, context)) { var introducedFieldName = IntroductionRules.GetName(adviceType.Namespace, adviceType.Name, introducedMemberName, memberName, isShared); lock (advisedType.Fields) { if (advisedType.Fields.All(f => f.Name != introducedFieldName)) { var fieldAttributes = (InjectAsPrivate ? FieldAttributes.Private : FieldAttributes.Public) | (isNotSerialized ? FieldAttributes.NotSerialized : 0); if (isStatic) { fieldAttributes |= FieldAttributes.Static; } Logging.WriteDebug("Introduced field type '{0}'", introducedFieldType.FullName); var introducedFieldTypeReference = TypeImporter.Import(moduleDefinition, introducedFieldType.ToTypeSig()); var introducedField = new FieldDefUser(introducedFieldName, new FieldSig(introducedFieldTypeReference), fieldAttributes); introducedField.CustomAttributes.Add(new CustomAttribute(markerAttribute)); advisedType.Fields.Add(introducedField); } } } }
/// <summary> /// Introduces the member. /// </summary> /// <param name="moduleDefinition">The module definition.</param> /// <param name="memberName">Name of the member.</param> /// <param name="memberType">Type of the member.</param> /// <param name="isStatic">if set to <c>true</c> [is static].</param> /// <param name="adviceType">The advice.</param> /// <param name="advisedType">The type definition.</param> /// <param name="markerAttributeCtor">The marker attribute ctor.</param> private void IntroduceMember(ModuleDefinition moduleDefinition, string memberName, TypeReference memberType, bool isStatic, TypeReference adviceType, TypeDefinition advisedType, MethodReference markerAttributeCtor) { TypeReference introducedFieldType; if (IsIntroduction(memberType, out introducedFieldType)) { var introducedFieldName = IntroductionRules.GetName(adviceType.Namespace, adviceType.Name, memberName); lock (advisedType.Fields) { if (advisedType.Fields.All(f => f.Name != introducedFieldName)) { var fieldAttributes = (InjectAsPrivate ? FieldAttributes.Private : FieldAttributes.Public) | FieldAttributes.NotSerialized; if (isStatic) { fieldAttributes |= FieldAttributes.Static; } Logger.WriteDebug("Introduced field type '{0}'", introducedFieldType.FullName); var introducedFieldTypeReference = moduleDefinition.SafeImport(introducedFieldType); var introducedField = new FieldDefinition(introducedFieldName, fieldAttributes, introducedFieldTypeReference); introducedField.CustomAttributes.Add(new CustomAttribute(markerAttributeCtor)); advisedType.Fields.Add(introducedField); } } } }
/// <summary> /// Finds the introduced field. /// </summary> /// <param name="advice">The advice.</param> /// <param name="adviceMemberInfo">The advice member information.</param> /// <param name="advisedType">Type of the advised.</param> /// <param name="advisedMemberName">Name of the advised member.</param> /// <returns></returns> /// <exception cref="InvalidOperationException">Internal error, can not find matching introduced field</exception> /// <exception cref="System.InvalidOperationException">Internal error, can not find matching introduced field</exception> internal static FieldInfo FindIntroducedField(IAdvice advice, MemberInfo adviceMemberInfo, Type advisedType, string advisedMemberName) { var introducedFieldType = GetIntroducedType(adviceMemberInfo); var adviceType = advice.GetType(); var introducedFieldName = IntroductionRules.GetName(adviceType.Namespace, adviceType.Name, advisedMemberName, adviceMemberInfo.Name); const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; var introducedField = FindIntroducedFieldByName(advisedType, introducedFieldName, introducedFieldName, bindingFlags) ?? FindIntroducedFieldByTypeAndAvailability(advisedType, introducedFieldType, adviceMemberInfo.IsStatic(), null, bindingFlags) ?? FindIntroducedFieldByTypeAndAvailability(advisedType, introducedFieldType, adviceMemberInfo.IsStatic(), introducedFieldName, bindingFlags); if (introducedField is null) { throw new InvalidOperationException("Internal error, can not find matching introduced field"); } var introducedFieldAttribute = introducedField.GetAttributes <IntroducedFieldAttribute>().Single(); introducedFieldAttribute.LinkID = introducedFieldName; return(introducedField); }
/// <summary> /// Finds the introduced field. /// </summary> /// <param name="advice">The advice.</param> /// <param name="adviceMemberInfo">The advice member information.</param> /// <param name="advisedType">Type of the advised.</param> /// <returns></returns> /// <exception cref="System.InvalidOperationException">Internal error, can not find matching introduced field</exception> internal static FieldInfo FindIntroducedField(IAdvice advice, MemberInfo adviceMemberInfo, Type advisedType) { var introducedFieldType = GetIntroducedType(adviceMemberInfo); var adviceType = advice.GetType(); var introducedFieldName = IntroductionRules.GetName(adviceType.Namespace, adviceType.Name, adviceMemberInfo.Name); var linkID = string.Format("{0}:{1}", adviceType.AssemblyQualifiedName, adviceMemberInfo.Name); const BindingFlags bindingFlags = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; var introducedField = FindIntroducedFieldByName(advisedType, introducedFieldName, linkID, bindingFlags) ?? FindIntroducedFieldByTypeAndAvailability(advisedType, introducedFieldType, adviceMemberInfo.IsStatic(), null, bindingFlags) ?? FindIntroducedFieldByTypeAndAvailability(advisedType, introducedFieldType, adviceMemberInfo.IsStatic(), linkID, bindingFlags); if (introducedField == null) { throw new InvalidOperationException("Internal error, can not find matching introduced field"); } var introducedFieldAttribute = introducedField.GetCustomAttribute <IntroducedFieldAttribute>(); introducedFieldAttribute.LinkID = linkID; return(introducedField); }