/// <summary> /// Can the advised interfaces be implemented by the introduction /// advice? /// </summary> /// <remarks> /// <p> /// Invoked <b>before</b> adding an /// <seealso cref="Oragon.Spring.Aop.IIntroductionAdvisor"/>. /// </p> /// </remarks> /// <exception cref="System.ArgumentException"> /// If the advised interfaces cannot be implemented by the introduction /// advice. /// </exception> /// <seealso cref="Oragon.Spring.Aop.IIntroductionAdvisor.Interfaces"/> /// <exception cref="System.ArgumentException"> /// If any of the <see cref="Interfaces"/> are not interface <see cref="System.Type"/>. /// </exception> public virtual void ValidateInterfaces() { foreach (Type intf in _interfaces) { BailIfNotAnInterfaceType(intf); if (!intf.IsAssignableFrom(_introduction.GetType())) { throw new ArgumentException("Introduction [" + _introduction.GetType().FullName + "] " + "does not implement interface '" + intf.FullName + "' specified in introduction advice."); } } }
/// <summary> /// Gets priority level from the specified advice. /// </summary> /// <param name="advice">The advice.</param> /// <returns></returns> public static int GetLevel(IAdvice advice) { var priorityAttribute = advice.GetType().GetCustomAttributes(typeof (Priority), true).Cast<Priority>().SingleOrDefault(); if (priorityAttribute != null) return priorityAttribute.Level; return DefaultLevel; }
/// <summary> /// Gets priority level from the specified advice. /// </summary> /// <param name="advice">The advice.</param> /// <returns></returns> public static int GetLevel(IAdvice advice) { var priorityAttribute = advice.GetType().GetCustomAttributes(typeof(PriorityAttribute), true).Cast <PriorityAttribute>().SingleOrDefault(); if (priorityAttribute != null) { return(priorityAttribute.Level); } return(DefaultLevel); }
private Type GetNonLazyType(IAdvice advice) { var type = advice.GetType(); if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(LazyAdvice <>)) { return(type.GetGenericArguments()[0]); } return(type); }
/// <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; }
/// <summary> /// Injects the introduced fields to advice. /// </summary> /// <param name="advice">The advice.</param> /// <param name="advisedType">Type of the advised.</param> private static void InjectIntroducedFields(IAdvice advice, Type advisedType) { // shame, but easy here if (advice == null) { return; } const BindingFlags adviceMembersBindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static; foreach (var memberInfo in advice.GetType().GetFieldsAndProperties(adviceMembersBindingFlags).Where(IsIntroduction)) { var memberValue = memberInfo.GetValue(advice); if (memberValue == null) { InjectIntroducedField(advice, memberInfo, advisedType); } } }
/// <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> /// 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> /// 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); }
/// <summary> /// Creates a new instance of the /// <see cref="Oragon.Spring.Aop.Support.DefaultIntroductionAdvisor"/> class using /// the supplied <paramref name="introduction"/> /// </summary> /// <remarks> /// <p> /// This constructor adds all interfaces implemented by the supplied /// <paramref name="introduction"/> (except the /// <see cref="AopAlliance.Aop.IAdvice"/> interface) to the list of /// interfaces to introduce. /// </p> /// </remarks> /// <param name="introduction">The introduction to use.</param> public DefaultIntroductionAdvisor(IAdvice introduction) : this(introduction, introduction.GetType().GetInterfaces()) { }
/// <summary> /// Injects the introduced fields to advice. /// </summary> /// <param name="advice">The advice.</param> /// <param name="advisedType">Type of the advised.</param> private static void InjectIntroducedFields(IAdvice advice, Type advisedType) { // shame, but easy here if (advice == null) return; const BindingFlags adviceMembersBindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static; foreach (var memberInfo in advice.GetType().GetFieldsAndProperties(adviceMembersBindingFlags).Where(IsIntroduction)) { var memberValue = memberInfo.GetValue(advice); if (memberValue == null) InjectIntroducedField(advice, memberInfo, advisedType); } }
/// <summary> /// Creates a new instance of the /// <see cref="Spring.Aop.Support.DefaultIntroductionAdvisor"/> class using /// the supplied <paramref name="introduction"/> /// </summary> /// <remarks> /// <p> /// This constructor adds all interfaces implemented by the supplied /// <paramref name="introduction"/> (except the /// <see cref="AopAlliance.Aop.IAdvice"/> interface) to the list of /// interfaces to introduce. /// </p> /// </remarks> /// <param name="introduction">The introduction to use.</param> public DefaultIntroductionAdvisor(IAdvice introduction) : this(introduction, introduction.GetType().GetInterfaces()) { }
public static IList <MemberInfo> GetIntroducedFields(IAdvice advice) { const BindingFlags adviceMembersBindingFlags = BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static; return(new ReadOnlyCollection <MemberInfo>(advice.GetType().GetFieldsAndProperties(adviceMembersBindingFlags).Where(IsIntroduction).ToArray())); }
public void Add(IAdvice advice, IPointcut pointcut) { _appliedAdvices.Add(new AppliedAdvice(advice, pointcut)); _blockedTypes.Add(advice.GetType()); }