예제 #1
0
 /// <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.");
         }
     }
 }
예제 #2
0
 /// <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;
 }
예제 #3
0
        /// <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);
        }
예제 #4
0
        private Type GetNonLazyType(IAdvice advice)
        {
            var type = advice.GetType();

            if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(LazyAdvice <>))
            {
                return(type.GetGenericArguments()[0]);
            }
            return(type);
        }
예제 #5
0
 /// <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;
 }
예제 #6
0
        /// <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);
                }
            }
        }
예제 #7
0
        /// <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);
        }
예제 #8
0
        /// <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);
            }
        }
예제 #9
0
        /// <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);
        }
예제 #10
0
 /// <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())
 {
 }
예제 #11
0
 /// <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())
		{
		}
예제 #13
0
        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()));
        }
예제 #14
0
 public void Add(IAdvice advice, IPointcut pointcut)
 {
     _appliedAdvices.Add(new AppliedAdvice(advice, pointcut));
     _blockedTypes.Add(advice.GetType());
 }