diff --git a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/InheritanceBasedAopConfigurer.cs b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/InheritanceBasedAopConfigurer.cs
new file mode 100644
index 00000000..df4c751d
--- /dev/null
+++ b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/InheritanceBasedAopConfigurer.cs
@@ -0,0 +1,368 @@
+#region License
+
+/*
+ * Copyright © 2002-2008 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#endregion
+
+#region Imports
+
+using System;
+using System.Collections;
+
+using AopAlliance.Aop;
+using Spring.Util;
+using Spring.Objects.Factory;
+using Spring.Objects.Factory.Config;
+using Spring.Objects.Factory.Support;
+using Spring.Aop;
+using Spring.Aop.Framework;
+using Spring.Aop.Framework.Adapter;
+using Spring.Aop.Framework.DynamicProxy;
+using Spring.Core;
+
+#endregion
+
+namespace Spring.Aop.Framework.AutoProxy
+{
+ ///
+ /// implementation that replaces a group of objects
+ /// with a 'true' inheritance based AOP mechanism that delegates
+ /// to the given interceptors before invoking the object itself.
+ ///
+ /// Bruno Baia
+ public class InheritanceBasedAopConfigurer : IObjectFactoryPostProcessor, IObjectFactoryAware, IOrdered
+ {
+ #region Fields
+
+ private IList objectNames;
+ private string[] interceptorNames = new string[0];
+ private bool proxyTargetAttributes = true;
+ private bool proxyDeclaredMembersOnly = true;
+ private bool proxyInterfaces = false;
+
+ private IObjectFactory objectFactory;
+ private int order = int.MaxValue;
+ private IAdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.Instance;
+
+ #endregion
+
+ #region Properties
+
+ ///
+ /// Set the names of the objects in IList fashioned way
+ /// that should automatically get intercepted.
+ ///
+ ///
+ /// A name can specify a prefix to match by ending with "*", e.g. "myObject,tx*"
+ /// will match the object named "myObject" and all objects whose name start with "tx".
+ ///
+ public virtual IList ObjectNames
+ {
+ set { objectNames = value; }
+ }
+
+ ///
+ /// Sets the common interceptors, a list of ,
+ /// and introduction object names.
+ ///
+ ///
+ ///
+ /// If this property isn't set, there will be zero common interceptors.
+ /// This is perfectly valid, if "specific" interceptors such as
+ /// matching Advisors are all we want.
+ ///
+ ///
+ ///
+ /// The list of ,
+ /// and introduction object names.
+ ///
+ ///
+ ///
+ public virtual string[] InterceptorNames
+ {
+ set { interceptorNames = value; }
+ }
+
+ ///
+ /// Is target type attributes, method attributes, method's return type attributes
+ /// and method's parameter attributes to be proxied in addition
+ /// to any interfaces declared on the proxied ?
+ ///
+ public virtual bool ProxyTargetAttributes
+ {
+ get { return this.proxyTargetAttributes; }
+ set { this.proxyTargetAttributes = value; }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether inherited members should be proxied.
+ ///
+ ///
+ /// if inherited members should be proxied;
+ /// otherwise, .
+ ///
+ public bool ProxyDeclaredMembersOnly
+ {
+ get { return proxyDeclaredMembersOnly; }
+ set { proxyDeclaredMembersOnly = value; }
+ }
+
+ ///
+ /// Gets or sets a value indicating whether interfaces members should be proxied.
+ ///
+ ///
+ /// if interfaces members should be proxied;
+ /// otherwise, .
+ ///
+ public bool ProxyInterfaces
+ {
+ get { return proxyInterfaces; }
+ set { proxyInterfaces = value; }
+ }
+
+ #endregion
+
+ #region IObjectFactoryAware Members
+
+ ///
+ /// Callback that supplies the owning factory to an object instance.
+ ///
+ ///
+ /// Owning
+ /// (may not be ). The object can immediately
+ /// call methods on the factory.
+ ///
+ ///
+ ///
+ /// Invoked after population of normal object properties but before an init
+ /// callback like 's
+ ///
+ /// method or a custom init-method.
+ ///
+ ///
+ ///
+ /// In case of initialization errors.
+ ///
+ public IObjectFactory ObjectFactory
+ {
+ set { objectFactory = value; }
+ }
+
+ #endregion
+
+ #region IObjectFactoryPostProcessor Members
+
+ ///
+ /// Allows for custom modification of an application context's object definitions.
+ ///
+ ///
+ ///
+ /// If the object name matches, replaces the type by a AOP proxied type based on inheritance.
+ ///
+ ///
+ public void PostProcessObjectFactory(IConfigurableListableObjectFactory factory)
+ {
+ string[] objectDefinitionNames = factory.GetObjectDefinitionNames();
+ for (int i = 0; i < objectDefinitionNames.Length; ++i)
+ {
+ string name = objectDefinitionNames[i];
+ if (IsObjectNameMatch(name))
+ {
+ IConfigurableObjectDefinition definition =
+ factory.GetObjectDefinition(name) as IConfigurableObjectDefinition;
+
+ if (definition == null || IsInfrastructureType(definition.ObjectType, name))
+ {
+ continue;
+ }
+
+ ProxyFactory pf = CreateProxyFactory(definition.ObjectType, name);
+
+ InheritanceAopProxyTypeBuilder iaptb = new InheritanceAopProxyTypeBuilder(pf);
+ iaptb.ProxyDeclaredMembersOnly = this.ProxyDeclaredMembersOnly;
+ Type type = iaptb.BuildProxyType();
+
+ definition.ObjectType = type;
+ definition.ConstructorArgumentValues.AddIndexedArgumentValue(definition.ConstructorArgumentValues.ArgumentCount, pf);
+ }
+ }
+ }
+
+ #endregion
+
+ #region IOrdered Members
+
+ ///
+ /// Return the order value of this object, where a higher value means greater in
+ /// terms of sorting.
+ ///
+ ///
+ /// Ordering which will apply to this class's implementation
+ /// of Ordered, used when applying multiple ObjectPostProcessors.
+ /// Default value is int.MaxValue, meaning that it's non-ordered.
+ ///
+ /// The order value.
+ public virtual int Order
+ {
+ get { return order; }
+ set { order = value; }
+ }
+
+ #endregion
+
+ #region Protected methods
+
+ ///
+ /// Determines whether the object is an infrastructure type,
+ /// IAdvisor, IAdvice, IAdvisors, AbstractAutoProxyCreator or InheritanceBasedAopConfigurer.
+ ///
+ /// The object type to compare
+ /// The name of the object
+ ///
+ /// true if [is infrastructure type] [the specified obj]; otherwise, false.
+ ///
+ protected virtual bool IsInfrastructureType(Type type, String name)
+ {
+ return typeof(IAdvisor).IsAssignableFrom(type)
+ || typeof(IAdvice).IsAssignableFrom(type)
+ || typeof(IAdvisors).IsAssignableFrom(type)
+ || typeof(AbstractAutoProxyCreator).IsAssignableFrom(type)
+ || typeof(InheritanceBasedAopConfigurer).IsAssignableFrom(type);
+ }
+
+ ///
+ /// Create an AOP proxy for the given object.
+ ///
+ /// Type of the object.
+ /// The name of the object.
+ /// The AOP Proxy for the object.
+ protected virtual ProxyFactory CreateProxyFactory(Type objectType, string objectName)
+ {
+ ProxyFactory proxyFactory = new ProxyFactory();
+ proxyFactory.ProxyTargetAttributes = this.ProxyTargetAttributes;
+ proxyFactory.ProxyTargetAttributes = this.ProxyDeclaredMembersOnly;
+ proxyFactory.TargetSource = new InheritanceBasedAopTargetSource(objectType);
+ if (!ProxyInterfaces)
+ {
+ proxyFactory.Interfaces = Type.EmptyTypes;
+ }
+
+ IAdvisor[] advisors = ResolveInterceptorNames();
+ foreach (IAdvisor advisor in advisors)
+ {
+ if (advisor is IIntroductionAdvisor)
+ {
+ proxyFactory.AddIntroduction((IIntroductionAdvisor)advisor);
+ }
+ else
+ {
+ proxyFactory.AddAdvisor(advisor);
+ }
+ }
+
+ return proxyFactory;
+ }
+
+ ///
+ /// Return if the given object name matches one of the object names specified.
+ ///
+ ///
+ ///
+ /// The default implementation checks for "xxx*", "*xxx" and "*xxx*" matches,
+ /// as well as direct equality. Can be overridden in subclasses.
+ ///
+ ///
+ /// the object name to check
+ /// if the names match
+ protected virtual bool IsObjectNameMatch(string objectName)
+ {
+ if (objectNames != null)
+ {
+ for (int i = 0; i < objectNames.Count; i++)
+ {
+ string mappedName = String.Copy((string)objectNames[i]);
+ if (PatternMatchUtils.SimpleMatch(mappedName, objectName))
+ {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ #endregion
+
+ #region Private Methods
+
+ private IAdvisor[] ResolveInterceptorNames()
+ {
+ ArrayList advisors = new ArrayList();
+ foreach (string name in interceptorNames)
+ {
+ object next = objectFactory.GetObject(name);
+ if (next is IAdvisors)
+ {
+ advisors.AddRange(((IAdvisors)next).Advisors);
+ }
+ else
+ {
+ advisors.Add(advisorAdapterRegistry.Wrap(next));
+ }
+ }
+ return (IAdvisor[])advisors.ToArray(typeof(IAdvisor));
+ }
+
+ #endregion
+
+ #region InheritanceBasedAopTargetSource inner class definition
+
+ private class InheritanceBasedAopTargetSource : ITargetSource
+ {
+ private Type _targetType;
+
+ public InheritanceBasedAopTargetSource(Type targetType)
+ {
+ _targetType = targetType;
+ }
+
+ #region ITargetSource Members
+
+ public object GetTarget()
+ {
+ return null;
+ }
+
+ public bool IsStatic
+ {
+ get { return true; }
+ }
+
+ public void ReleaseTarget(object target)
+ {
+ }
+
+ public Type TargetType
+ {
+ get { return _targetType; }
+ }
+
+ #endregion
+ }
+
+ #endregion
+ }
+}
diff --git a/src/Spring/Spring.Aop/Spring.Aop.2005.csproj b/src/Spring/Spring.Aop/Spring.Aop.2005.csproj
index dd9fc546..59be97d4 100644
--- a/src/Spring/Spring.Aop/Spring.Aop.2005.csproj
+++ b/src/Spring/Spring.Aop/Spring.Aop.2005.csproj
@@ -120,6 +120,7 @@
+
diff --git a/src/Spring/Spring.Aop/Spring.Aop.2008.csproj b/src/Spring/Spring.Aop/Spring.Aop.2008.csproj
index 684acb96..eee83f5b 100644
--- a/src/Spring/Spring.Aop/Spring.Aop.2008.csproj
+++ b/src/Spring/Spring.Aop/Spring.Aop.2008.csproj
@@ -136,6 +136,7 @@
+