You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@avalon.apache.org by ha...@apache.org on 2004/08/31 16:22:44 UTC

svn commit: rev 37253 - in avalon/trunk/central/laboratory/avalon-net: Castle/MicroKernel Castle/MicroKernel/Handler Castle/MicroKernel/Interceptor Castle/MicroKernel/Interceptor/Default Castle/MicroKernel/MicroKernelTest Castle/MicroKernel/MicroKernelTest/Interceptor Castle/MicroKernel/Subsystems/Configuration Castle/MicroKernel/Subsystems/Configuration/Default DynamicProxy/DynamicProxyTest Framework/AvalonFrameworkTest

Author: hammett
Date: Tue Aug 31 07:22:41 2004
New Revision: 37253

Added:
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/AbstractInterceptor.cs   (contents, props changed)
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/Default/
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/Default/DefaultInterceptedComponentBuilder.cs   (contents, props changed)
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/Default/InterceptedComponent.cs   (contents, props changed)
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/IInterceptedComponent.cs   (contents, props changed)
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/IInterceptedComponentBuilder.cs   (contents, props changed)
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/IInterceptor.cs   (contents, props changed)
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Interceptor/
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Interceptor/AbstractInterceptorTestCase.cs
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Interceptor/DefaultInterceptedComponentBuilderTestCase.cs
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Interceptor/InterceptedComponentTestCase.cs   (contents, props changed)
Modified:
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Apache.Avalon.Castle.MicroKernel.csproj
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/AssertUtil.cs
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/BaseKernel.cs
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Handler/AbstractHandler.cs
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Handler/IHandler.cs
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/IKernelEvents.cs
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernel.sln
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Apache.Avalon.Castle.MicroKernel.Test.csproj
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Subsystems/Configuration/Default/DefaultConfigurationManager.cs
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Subsystems/Configuration/IConfigurationManager.cs
   avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Apache.Avalon.DynamicProxy.Test.csproj
   avalon/trunk/central/laboratory/avalon-net/Framework/AvalonFrameworkTest/Apache.Avalon.Framework.Test.csproj
Log:
Interceptor into core. Ability to plug in facilities to go.

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Apache.Avalon.Castle.MicroKernel.csproj
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Apache.Avalon.Castle.MicroKernel.csproj	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Apache.Avalon.Castle.MicroKernel.csproj	Tue Aug 31 07:22:41 2004
@@ -129,6 +129,11 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "IKernelEvents.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "IKernelSubsystem.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -309,6 +314,36 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "Interceptor\AbstractInterceptor.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Interceptor\IInterceptedComponent.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Interceptor\IInterceptedComponentBuilder.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Interceptor\IInterceptor.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Interceptor\Default\DefaultInterceptedComponentBuilder.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Interceptor\Default\InterceptedComponent.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "Lifestyle\ILifestyleManager.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -415,21 +450,6 @@
                 />
                 <File
                     RelPath = "Subsystems\Context\Default\ContextManager.cs"
-                    SubType = "Code"
-                    BuildAction = "Compile"
-                />
-                <File
-                    RelPath = "Subsystems\Events\EventManagerData.cs"
-                    SubType = "Code"
-                    BuildAction = "Compile"
-                />
-                <File
-                    RelPath = "Subsystems\Events\IEventManager.cs"
-                    SubType = "Code"
-                    BuildAction = "Compile"
-                />
-                <File
-                    RelPath = "Subsystems\Events\Default\EventManager.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
                 />

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/AssertUtil.cs
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/AssertUtil.cs	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/AssertUtil.cs	Tue Aug 31 07:22:41 2004
@@ -33,6 +33,36 @@
 					argName, 
 					String.Format("Argument {0} can't be null", argName) );
 			}
-		}
+		}
+
+		public static void ArgumentMustBeInterface( Type argValue, String argName )
+		{
+			if (argValue != null && !argValue.IsInterface)
+			{
+				throw new ArgumentNullException(
+					argName, 
+					String.Format("Argument {0} must be an interface", argName) );
+			}
+		}
+
+		public static void ArgumentMustNotBeInterface( Type argValue, String argName )
+		{
+			if (argValue != null && argValue.IsInterface)
+			{
+				throw new ArgumentNullException(
+					argName, 
+					String.Format("Argument {0} can't be an interface", argName) );
+			}
+		}
+
+		public static void ArgumentMustNotBeAbstract( Type argValue, String argName )
+		{
+			if (argValue != null && argValue.IsAbstract)
+			{
+				throw new ArgumentNullException(
+					argName, 
+					String.Format("Argument {0} can't be abstract", argName) );
+			}
+		}
 	}
 }

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/BaseKernel.cs
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/BaseKernel.cs	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/BaseKernel.cs	Tue Aug 31 07:22:41 2004
@@ -26,7 +26,7 @@
 	/// </summary>
 	public class BaseKernel : IKernel, IDisposable
 	{
-        private static readonly object ComponentAddedEvent = new object();
+        private static readonly object ComponentRegisteredEvent = new object();
         private static readonly object ComponentCreatedEvent = new object();
         private static readonly object ComponentDestroyedEvent = new object();
 
@@ -78,19 +78,10 @@
 			AssertUtil.ArgumentNotNull( key, "key" );
 			AssertUtil.ArgumentNotNull( service, "service" );
 			AssertUtil.ArgumentNotNull( implementation, "implementation" );
+			AssertUtil.ArgumentMustBeInterface( service, "service" );
+			AssertUtil.ArgumentMustNotBeInterface( implementation, "implementation" );
+			AssertUtil.ArgumentMustNotBeAbstract( implementation, "implementation" );
 			
-			if (!service.IsInterface)
-			{
-				throw new ArgumentException("service must be an interface");
-			}
-			if (implementation.IsInterface)
-			{
-				throw new ArgumentException("implementation can't be an interface");
-			}
-            if (implementation.IsAbstract)
-            {
-                throw new ArgumentException("implementation can't be abstract");
-            }
             if (!service.IsAssignableFrom(implementation))
             {
 				throw new ArgumentException("The specified implementation does not implement the service interface");
@@ -106,10 +97,10 @@
             OnNewHandler( model, key, service, implementation, handler);
         }
 
-        public event ComponentDataDelegate ComponentAdded
+        public event ComponentDataDelegate ComponentRegistered
         {
-            add { m_events.AddHandler(ComponentAddedEvent, value); }
-            remove { m_events.RemoveHandler(ComponentAddedEvent, value); }
+            add { m_events.AddHandler(ComponentRegisteredEvent, value); }
+            remove { m_events.RemoveHandler(ComponentRegisteredEvent, value); }
         }
 
         /// <summary>
@@ -264,13 +255,13 @@
 			// AddSubsystem( KernelConstants.EVENTS, new EventManager() );
 		}
 
-        protected virtual void RaiseComponentAdded(IComponentModel model, String key, Type service, Type implementation, IHandler handler)
+        protected virtual void RaiseComponentAdded(IComponentModel model, String key, IHandler handler)
         {
-            ComponentDataDelegate eventDelegate = (ComponentDataDelegate) m_events[ComponentAddedEvent];
+            ComponentDataDelegate eventDelegate = (ComponentDataDelegate) m_events[ComponentRegisteredEvent];
             
             if (eventDelegate != null)
             {
-                eventDelegate(model, key, service, implementation, handler);
+                eventDelegate(model, key, handler);
             }
         }
 
@@ -278,7 +269,7 @@
 		{
 			m_services[ service ] = handler;
 
-            RaiseComponentAdded( model, key, service, implementation, handler );
+            RaiseComponentAdded( model, key, handler );
 
             if (model.ActivationPolicy == Apache.Avalon.Framework.Activation.Start)
             {

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Handler/AbstractHandler.cs
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Handler/AbstractHandler.cs	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Handler/AbstractHandler.cs	Tue Aug 31 07:22:41 2004
@@ -41,8 +41,7 @@
 		/// <summary>
 		/// 
 		/// </summary>
-		/// <param name="service"></param>
-		/// <param name="implementation"></param>
+		/// <param name="model"></param>
 		public AbstractHandler( IComponentModel model )
 		{
 			AssertUtil.ArgumentNotNull( model, "model" );
@@ -59,7 +58,7 @@
 
 		public virtual object Resolve()
 		{
-			if (m_state == State.WaitingDependency)
+			if (ActualState == State.WaitingDependency)
 			{
 				throw new HandlerException("Can't Resolve component. It has dependencies to be satisfied.");
 			}

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Handler/IHandler.cs
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Handler/IHandler.cs	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Handler/IHandler.cs	Tue Aug 31 07:22:41 2004
@@ -1,45 +1,42 @@
-// Copyright 2004 The Apache Software Foundation
-// 
-// 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.
-
-namespace Apache.Avalon.Castle.MicroKernel
-{
-	using System;
-
-	/// <summary>
-	/// Summary description for IHandler.
-	/// </summary>
-	public interface IHandler : IResolver
-	{
-		/// <summary>
-		/// 
-		/// </summary>
-		/// <param name="kernel"></param>
-		void Init( IKernel kernel );
-
-		/// <summary>
-		/// 
-		/// </summary>
-		State ActualState
-		{
-			get;
-		}
-
-		/// <summary>
-		/// 
-		/// </summary>
-		/// <param name="instance"></param>
-		/// <returns></returns>
-		bool IsOwner( object instance );
-	}
-}
+ // Copyright 2004 The Apache Software Foundation
+// 
+// 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.
+
+namespace Apache.Avalon.Castle.MicroKernel
+{
+	using System;
+
+	/// <summary>
+	/// Summary description for IHandler.
+	/// </summary>
+	public interface IHandler : IResolver
+	{
+		/// <summary>
+		/// 
+		/// </summary>
+		/// <param name="kernel"></param>
+		void Init(IKernel kernel);
+
+		/// <summary>
+		/// 
+		/// </summary>
+		State ActualState { get; }
+
+		/// <summary>
+		/// 
+		/// </summary>
+		/// <param name="instance"></param>
+		/// <returns></returns>
+		bool IsOwner(object instance);
+	}
+}
\ No newline at end of file

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/IKernelEvents.cs
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/IKernelEvents.cs	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/IKernelEvents.cs	Tue Aug 31 07:22:41 2004
@@ -17,8 +17,13 @@
 	using System;
 
 	using Apache.Avalon.Castle.MicroKernel.Model;
+	using Apache.Avalon.Castle.MicroKernel.Interceptor;
 
-    public delegate void ComponentDataDelegate( IComponentModel model, String key, Type service, Type implementation, IHandler handler );
+    public delegate void ComponentDataDelegate( IComponentModel model, String key, IHandler handler );
+
+	public delegate void InterceptionDelegate( IComponentModel model, String key, IHandler handler, IInterceptedComponent interceptedComponent );
+
+	public delegate void ComponentInstanceDelegate( IComponentModel model, String key, IHandler handler, object instance );
 
     /// <summary>
     /// 
@@ -28,6 +33,16 @@
         /// <summary>
         /// 
         /// </summary>
-        event ComponentDataDelegate ComponentAdded;
-    }
+        event ComponentDataDelegate ComponentRegistered;
+	
+		/// <summary>
+		/// 
+		/// </summary>
+		// event InterceptionDelegate ComponentCreated;
+
+		/// <summary>
+		/// 
+		/// </summary>
+		// event ComponentInstanceDelegate ComponentDestroyed;
+	}
 }

Added: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/AbstractInterceptor.cs
==============================================================================
--- (empty file)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/AbstractInterceptor.cs	Tue Aug 31 07:22:41 2004
@@ -0,0 +1,62 @@
+// Copyright 2004 The Apache Software Foundation
+// 
+// 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.
+
+namespace Apache.Avalon.Castle.MicroKernel.Interceptor
+{
+	/// <summary>
+	/// Abstract implementation for <see cref="IInterceptor"/>
+	/// which implements the Next property. Implementors should override
+	/// the Process method and invoke the base class to invoke the next
+	/// interceptor in the chain.
+	/// </summary>
+	public abstract class AbstractInterceptor : IInterceptor
+	{
+		private IInterceptor m_next;
+
+		public AbstractInterceptor()
+		{
+		}
+
+		#region IInterceptor Members
+
+		/// <summary>
+		/// Invokes the Next interceptor in the chain
+		/// </summary>
+		/// <param name="instance"></param>
+		/// <param name="method"></param>
+		/// <param name="arguments"></param>
+		/// <returns></returns>
+		public virtual object Process(object instance, System.Reflection.MethodInfo method, params object[] arguments)
+		{
+			return Next.Process( instance, method, arguments );
+		}
+
+		/// <summary>
+		/// Get and set the next interceptor in the chain
+		/// </summary>
+		public IInterceptor Next
+		{
+			get
+			{
+				return m_next;
+			}
+			set
+			{
+				m_next = value;
+			}
+		}
+
+		#endregion
+	}
+}

Added: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/Default/DefaultInterceptedComponentBuilder.cs
==============================================================================
--- (empty file)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/Default/DefaultInterceptedComponentBuilder.cs	Tue Aug 31 07:22:41 2004
@@ -0,0 +1,87 @@
+// Copyright 2004 The Apache Software Foundation
+// 
+// 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.
+
+namespace Apache.Avalon.Castle.MicroKernel.Interceptor.Default
+{
+	using System;
+	using System.Reflection;
+
+	using Apache.Avalon.DynamicProxy;
+
+	/// <summary>
+	/// Summary description for DefaultInterceptorManager.
+	/// </summary>
+	public class DefaultInterceptedComponentBuilder : IInterceptedComponentBuilder
+	{
+		#region IInterceptorManager Members
+
+		/// <summary>
+		/// 
+		/// </summary>
+		/// <param name="instance"></param>
+		/// <param name="service"></param>
+		/// <returns></returns>
+		public IInterceptedComponent CreateInterceptedComponent(object instance, Type service)
+		{
+			AssertUtil.ArgumentNotNull(instance, "instance");
+			AssertUtil.ArgumentNotNull(service, "service");
+			AssertUtil.ArgumentMustBeInterface(service, "service");
+
+			InterceptedComponent intercepted = new InterceptedComponent(instance);
+
+			object proxy = ProxyGenerator.CreateProxy(service, new InterceptorInvocationHandler(intercepted) );
+			intercepted.SetProxiedInstance(proxy);
+
+			return intercepted;
+		}
+
+		#endregion
+
+		/// <summary>
+		/// Implementation of <see cref="DynamicProxy.IInvocationHandler"/>
+		/// which delegates the execution to the interceptor chain.
+		/// </summary>
+		public sealed class InterceptorInvocationHandler : IInvocationHandler
+		{
+			private InterceptedComponent m_interceptedComponent;
+
+			/// <summary>
+			/// Constructs an InterceptorInvocationHandler
+			/// </summary>
+			/// <param name="interceptedComponent"></param>
+			public InterceptorInvocationHandler(InterceptedComponent interceptedComponent)
+			{
+				AssertUtil.ArgumentNotNull( interceptedComponent, "interceptedComponent" );
+				m_interceptedComponent = interceptedComponent;
+			}
+
+			#region IInvocationHandler Members
+
+			/// <summary>
+			/// Pending.
+			/// </summary>
+			/// <param name="proxy"></param>
+			/// <param name="method"></param>
+			/// <param name="arguments"></param>
+			/// <returns></returns>
+			public object Invoke(object proxy, MethodInfo method, params object[] arguments)
+			{
+				object instance = m_interceptedComponent.Instance;
+				return m_interceptedComponent.InterceptorChain.Process( instance, method, arguments );
+			}
+
+			#endregion
+		}
+	}
+}
\ No newline at end of file

Added: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/Default/InterceptedComponent.cs
==============================================================================
--- (empty file)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/Default/InterceptedComponent.cs	Tue Aug 31 07:22:41 2004
@@ -0,0 +1,127 @@
+// Copyright 2004 The Apache Software Foundation
+// 
+// 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.
+
+namespace Apache.Avalon.Castle.MicroKernel.Interceptor.Default
+{
+	using System.Reflection;
+
+	/// <summary>
+	/// Implementation for <see cref="IInterceptedComponent"/>
+	/// which holds a component instance, its proxied version and 
+	/// an interceptor chain.
+	/// </summary>
+	public class InterceptedComponent : IInterceptedComponent
+	{
+		private object m_instance;
+		private object m_proxy;
+		private IInterceptor m_interceptor = new TailInterceptor();
+
+		/// <summary>
+		/// Constructs an InterceptedComponent
+		/// </summary>
+		/// <param name="instance"></param>
+		public InterceptedComponent(object instance)
+		{
+			AssertUtil.ArgumentNotNull(instance, "instance");
+			m_instance = instance;
+		}
+
+		/// <summary>
+		/// Sets the proxied instance.
+		/// </summary>
+		/// <param name="proxy"></param>
+		public void SetProxiedInstance(object proxy)
+		{
+			AssertUtil.ArgumentNotNull(proxy, "proxy");
+			m_proxy = proxy;
+		}
+
+		/// <summary>
+		/// Returns the component instance, non-proxied.
+		/// </summary>
+		public object Instance
+		{
+			get { return m_instance; }
+		}
+
+		#region IInterceptedComponent Members
+
+		/// <summary>
+		/// Add the interceptor in the argument as the first interceptor
+		/// and set its next to the interceptor that we have. In the first
+		/// execution it will be the TailInterceptor.
+		/// </summary>
+		/// <param name="interceptor"></param>
+		public virtual void Add(IInterceptor interceptor)
+		{
+			AssertUtil.ArgumentNotNull(interceptor, "interceptor");
+
+			interceptor.Next = m_interceptor;
+			m_interceptor = interceptor;
+		}
+
+		/// <summary>
+		/// Returns the proxied instance, that should be available 
+		/// to the outside world
+		/// </summary>
+		public virtual object ProxiedInstance
+		{
+			get { return m_proxy; }
+		}
+
+		/// <summary>
+		/// Returns the first interceptor. A call to Process should 
+		/// start the execution chain by itself.
+		/// </summary>
+		public virtual IInterceptor InterceptorChain
+		{
+			get { return m_interceptor; }
+		}
+
+		#endregion
+
+		/// <summary>
+		/// Represents the last node in the method execution chain.
+		/// It - surprise, surprise - invokes the method on the object.
+		/// </summary>
+		public sealed class TailInterceptor : IInterceptor
+		{
+			#region IInterceptor Members
+
+			/// <summary>
+			/// Invokes the method on the object instance.
+			/// </summary>
+			/// <param name="instance">The actual component instance</param>
+			/// <param name="method">Method being executed</param>
+			/// <param name="arguments">Method arguments</param>
+			/// <returns>Should return the method result</returns>
+			public object Process(object instance, MethodInfo method, params object[] arguments)
+			{
+				return method.Invoke(instance, arguments);
+			}
+
+			/// <summary>
+			/// There is no need to have the property implemented as
+			/// there is no next interceptor after the TailInterceptor
+			/// </summary>
+			public IInterceptor Next
+			{
+				get { return null; }
+				set { }
+			}
+
+			#endregion
+		}
+	}
+}
\ No newline at end of file

Added: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/IInterceptedComponent.cs
==============================================================================
--- (empty file)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/IInterceptedComponent.cs	Tue Aug 31 07:22:41 2004
@@ -0,0 +1,30 @@
+// Copyright 2004 The Apache Software Foundation
+// 
+// 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.
+
+namespace Apache.Avalon.Castle.MicroKernel.Interceptor
+{
+	using System;
+
+	/// <summary>
+	/// Summary description for IInterceptedComponent.
+	/// </summary>
+	public interface IInterceptedComponent
+	{
+		object ProxiedInstance { get; }
+
+		void Add( IInterceptor interceptor );
+
+		IInterceptor InterceptorChain { get; }
+	}
+}

Added: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/IInterceptedComponentBuilder.cs
==============================================================================
--- (empty file)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/IInterceptedComponentBuilder.cs	Tue Aug 31 07:22:41 2004
@@ -0,0 +1,36 @@
+// Copyright 2004 The Apache Software Foundation
+// 
+// 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.
+
+namespace Apache.Avalon.Castle.MicroKernel.Interceptor
+{
+	using System;
+
+	/// <summary>
+	/// Implementors should define their strategy to create 
+	/// <see cref="IInterceptedComponent"/> instance for the
+	/// specified component instance.
+	/// </summary>
+	public interface IInterceptedComponentBuilder
+	{
+		/// <summary>
+		/// Should return an implementation of <see cref="IInterceptedComponent"/>
+		/// which should be responsible for exposing a proxied instance 
+		/// capable of dealing with an interception chain.
+		/// </summary>
+		/// <param name="instance"></param>
+		/// <param name="service"></param>
+		/// <returns></returns>
+		IInterceptedComponent CreateInterceptedComponent( object instance, Type service );
+	}
+}

Added: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/IInterceptor.cs
==============================================================================
--- (empty file)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/IInterceptor.cs	Tue Aug 31 07:22:41 2004
@@ -0,0 +1,40 @@
+// Copyright 2004 The Apache Software Foundation
+// 
+// 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.
+
+namespace Apache.Avalon.Castle.MicroKernel.Interceptor
+{
+	using System;
+
+	/// <summary>
+	/// Represent a step - and a concern - during the 
+	/// execution of a method.
+	/// </summary>
+	public interface IInterceptor
+	{
+		/// <summary>
+		/// Implementors should performs its logic before and/or 
+		/// after invoking the Next.Process
+		/// </summary>
+		/// <param name="instance">The actual component instance</param>
+		/// <param name="method">Method being executed</param>
+		/// <param name="arguments">Method arguments</param>
+		/// <returns>Should return the method result</returns>
+		object Process( object instance, System.Reflection.MethodInfo method, params object[] arguments );
+
+		/// <summary>
+		/// Holds the next interceptor in the chain.
+		/// </summary>
+		IInterceptor Next {get; set;}
+	}
+}

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernel.sln
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernel.sln	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernel.sln	Tue Aug 31 07:22:41 2004
@@ -7,10 +7,6 @@
 	ProjectSection(ProjectDependencies) = postProject
 	EndProjectSection
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Avalon.Castle.Facilities.Aspects", "..\Facilities\Aspects\Apache.Avalon.Castle.Facilities.Aspects.csproj", "{17546A9D-FAE9-42D1-BF36-740187216D34}"
-	ProjectSection(ProjectDependencies) = postProject
-	EndProjectSection
-EndProject
 Global
 	GlobalSection(SolutionConfiguration) = preSolution
 		Debug = Debug
@@ -25,10 +21,6 @@
 		{50442F0D-987F-4A8D-B38C-DFA855B9249E}.Debug.Build.0 = Debug|.NET
 		{50442F0D-987F-4A8D-B38C-DFA855B9249E}.Release.ActiveCfg = Release|.NET
 		{50442F0D-987F-4A8D-B38C-DFA855B9249E}.Release.Build.0 = Release|.NET
-		{17546A9D-FAE9-42D1-BF36-740187216D34}.Debug.ActiveCfg = Debug|.NET
-		{17546A9D-FAE9-42D1-BF36-740187216D34}.Debug.Build.0 = Debug|.NET
-		{17546A9D-FAE9-42D1-BF36-740187216D34}.Release.ActiveCfg = Release|.NET
-		{17546A9D-FAE9-42D1-BF36-740187216D34}.Release.Build.0 = Release|.NET
 	EndGlobalSection
 	GlobalSection(ExtensibilityGlobals) = postSolution
 	EndGlobalSection

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Apache.Avalon.Castle.MicroKernel.Test.csproj
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Apache.Avalon.Castle.MicroKernel.Test.csproj	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Apache.Avalon.Castle.MicroKernel.Test.csproj	Tue Aug 31 07:22:41 2004
@@ -92,7 +92,7 @@
                 <Reference
                     Name = "nunit.framework"
                     AssemblyName = "nunit.framework"
-                    HintPath = "..\..\..\..\..\..\..\..\..\..\dotnet\NUnit2\bin\nunit.framework.dll"
+                    HintPath = "..\..\..\..\..\..\..\dotnet\NUnit2\bin\nunit.framework.dll"
                 />
             </References>
         </Build>
@@ -144,16 +144,6 @@
                     BuildAction = "Compile"
                 />
                 <File
-                    RelPath = "EventManagerTestCase.cs"
-                    SubType = "Code"
-                    BuildAction = "Compile"
-                />
-                <File
-                    RelPath = "EventSubsystemTestCase.cs"
-                    SubType = "Code"
-                    BuildAction = "Compile"
-                />
-                <File
                     RelPath = "LoggerManagerTestCase.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -305,6 +295,21 @@
                 />
                 <File
                     RelPath = "Concerns\StartConcernTestCase.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Interceptor\AbstractInterceptorTestCase.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Interceptor\DefaultInterceptedComponentBuilderTestCase.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Interceptor\InterceptedComponentTestCase.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
                 />

Added: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Interceptor/AbstractInterceptorTestCase.cs
==============================================================================
--- (empty file)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Interceptor/AbstractInterceptorTestCase.cs	Tue Aug 31 07:22:41 2004
@@ -0,0 +1,54 @@
+// Copyright 2004 The Apache Software Foundation
+// 
+// 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.
+
+namespace Apache.Avalon.Castle.MicroKernel.Test.Interceptor
+{
+	using NUnit.Framework;
+
+	using Apache.Avalon.Castle.MicroKernel.Interceptor;
+
+	/// <summary>
+	/// Summary description for AbstractInterceptorTestCase.
+	/// </summary>
+	[TestFixture]
+	public class AbstractInterceptorTestCase : Assertion
+	{
+		[Test]
+		public void CheckAbstractImplementation()
+		{
+			TestInterceptor testInterceptor = new TestInterceptor();
+			EndInterceptor endInterceptor = new EndInterceptor();
+
+			testInterceptor.Next = endInterceptor;
+
+			AssertEquals( 1, testInterceptor.Process( this, null ) );
+		}
+
+		public class TestInterceptor : AbstractInterceptor
+		{
+			public override object Process(object instance, System.Reflection.MethodInfo method, params object[] arguments)
+			{
+				return base.Process (instance, method, arguments);
+			}
+		}
+
+		public class EndInterceptor : AbstractInterceptor
+		{
+			public override object Process(object instance, System.Reflection.MethodInfo method, params object[] arguments)
+			{
+				return 1;
+			}
+		}
+	}
+}

Added: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Interceptor/DefaultInterceptedComponentBuilderTestCase.cs
==============================================================================
--- (empty file)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Interceptor/DefaultInterceptedComponentBuilderTestCase.cs	Tue Aug 31 07:22:41 2004
@@ -0,0 +1,45 @@
+// Copyright 2004 The Apache Software Foundation
+// 
+// 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.
+
+namespace Apache.Avalon.Castle.MicroKernel.Test.Interceptor
+{
+	using NUnit.Framework;
+
+	using Apache.Avalon.Castle.MicroKernel.Interceptor;
+	using Apache.Avalon.Castle.MicroKernel.Interceptor.Default;
+	using Apache.Avalon.Castle.MicroKernel.Test.Components;
+
+	/// <summary>
+	/// Summary description for DefaultInterceptedComponentBuilderTestCase.
+	/// </summary>
+	[TestFixture]
+	public class DefaultInterceptedComponentBuilderTestCase : Assertion
+	{
+		[Test]
+		public void CreateInterceptedComponent()
+		{
+			IInterceptedComponentBuilder interceptorManager = new DefaultInterceptedComponentBuilder();
+
+			IMailService mailService = new SimpleMailService();
+
+			IInterceptedComponent component = 
+				interceptorManager.CreateInterceptedComponent( 
+					mailService, typeof(IMailService) );
+			AssertNotNull( "Proxy not created", component.ProxiedInstance );
+
+			IMailService proxiedMailService = component.ProxiedInstance as IMailService;
+			AssertNotNull( "Could not cast to IMailService", proxiedMailService );
+		}
+	}
+}

Added: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Interceptor/InterceptedComponentTestCase.cs
==============================================================================
--- (empty file)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Interceptor/InterceptedComponentTestCase.cs	Tue Aug 31 07:22:41 2004
@@ -0,0 +1,123 @@
+using System.Reflection;
+// Copyright 2004 The Apache Software Foundation
+// 
+// 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.
+
+namespace Apache.Avalon.Castle.MicroKernel.Test.Interceptor
+{
+	using NUnit.Framework;
+
+	using Apache.Avalon.Castle.MicroKernel.Interceptor;
+	using Apache.Avalon.Castle.MicroKernel.Interceptor.Default;
+
+	/// <summary>
+	/// Summary description for InterceptedComponentTestCase.
+	/// </summary>
+	[TestFixture]
+	public class InterceptedComponentTestCase : Assertion
+	{
+		private IInterceptedComponent m_component;
+		private IService m_service;
+		private IService m_proxiedService;
+
+		[SetUp]
+		public void Init()
+		{
+			IInterceptedComponentBuilder interceptorManager = new DefaultInterceptedComponentBuilder();
+
+			m_service = new ServiceImpl();
+
+			m_component = interceptorManager.CreateInterceptedComponent(
+				m_service, typeof (IService));
+
+			m_proxiedService = m_component.ProxiedInstance as IService;
+		}
+
+		[Test]
+		public void TailInvocationOnly()
+		{
+			Assert(!m_service.Done);
+			m_proxiedService.DoSomething();
+			Assert(m_service.Done);
+		}
+
+		[Test]
+		public void NewInterceptor()
+		{
+			DummyInterceptor interceptor = new DummyInterceptor();
+
+			m_component.Add(interceptor);
+
+			Assert(!interceptor.Invoked);
+
+			Assert(!m_service.Done);
+			m_proxiedService.DoSomething();
+			Assert(m_service.Done);
+
+			Assert(interceptor.Invoked);
+		}
+
+		public class DummyInterceptor : IInterceptor
+		{
+			private bool m_invoked = false;
+			private IInterceptor m_next;
+
+			public bool Invoked
+			{
+				get { return m_invoked; }
+			}
+
+			#region IInterceptor Members
+
+			public object Process(object instance, MethodInfo method, params object[] arguments)
+			{
+				m_invoked = true;
+				return Next.Process(instance, method, arguments);
+			}
+
+			public IInterceptor Next
+			{
+				get { return m_next; }
+				set { m_next = value; }
+			}
+
+			#endregion
+		}
+
+		public interface IService
+		{
+			void DoSomething();
+
+			bool Done { get; }
+		}
+
+		public class ServiceImpl : IService
+		{
+			private bool m_done = false;
+
+			#region IService Members
+
+			public void DoSomething()
+			{
+				m_done = true;
+			}
+
+			public bool Done
+			{
+				get { return m_done; }
+			}
+
+			#endregion
+		}
+	}
+}
\ No newline at end of file

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Subsystems/Configuration/Default/DefaultConfigurationManager.cs
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Subsystems/Configuration/Default/DefaultConfigurationManager.cs	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Subsystems/Configuration/Default/DefaultConfigurationManager.cs	Tue Aug 31 07:22:41 2004
@@ -16,11 +16,8 @@
 {
 	using System;
 	using System.Collections;
-	using System.Collections.Specialized;
-	using System.Configuration;
 
 	using Apache.Avalon.Framework;
-	using Apache.Avalon.Castle.MicroKernel.Model;
 	using Apache.Avalon.Castle.MicroKernel.Subsystems;
 
 	/// <summary>
@@ -45,7 +42,7 @@
 		/// Implementation should return a configuration for 
 		/// the component.
 		/// </summary>
-		/// <param name="model"></param>
+		/// <param name="componentName"></param>
 		/// <returns></returns>
 		public IConfiguration GetConfiguration(String componentName)
 		{

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Subsystems/Configuration/IConfigurationManager.cs
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Subsystems/Configuration/IConfigurationManager.cs	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Subsystems/Configuration/IConfigurationManager.cs	Tue Aug 31 07:22:41 2004
@@ -17,7 +17,6 @@
 	using System;
 
 	using Apache.Avalon.Framework;
-	using Apache.Avalon.Castle.MicroKernel.Model;
 
 	/// <summary>
 	/// Summary description for IConfigurationManager.
@@ -28,7 +27,7 @@
 		/// Implementation should return a configuration for 
 		/// the component.
 		/// </summary>
-		/// <param name="model"></param>
+		/// <param name="componentName"></param>
 		/// <returns></returns>
 		IConfiguration GetConfiguration( String componentName );
 

Modified: avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Apache.Avalon.DynamicProxy.Test.csproj
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Apache.Avalon.DynamicProxy.Test.csproj	(original)
+++ avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Apache.Avalon.DynamicProxy.Test.csproj	Tue Aug 31 07:22:41 2004
@@ -87,7 +87,7 @@
                 <Reference
                     Name = "nunit.framework"
                     AssemblyName = "nunit.framework"
-                    HintPath = "..\..\..\..\..\..\..\..\..\dotnet\NUnit2\bin\nunit.framework.dll"
+                    HintPath = "..\..\..\..\..\..\dotnet\NUnit2\bin\nunit.framework.dll"
                 />
             </References>
         </Build>

Modified: avalon/trunk/central/laboratory/avalon-net/Framework/AvalonFrameworkTest/Apache.Avalon.Framework.Test.csproj
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Framework/AvalonFrameworkTest/Apache.Avalon.Framework.Test.csproj	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Framework/AvalonFrameworkTest/Apache.Avalon.Framework.Test.csproj	Tue Aug 31 07:22:41 2004
@@ -80,14 +80,14 @@
                     HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.0.3705\System.XML.dll"
                 />
                 <Reference
-                    Name = "nunit.framework"
-                    AssemblyName = "nunit.framework"
-                    HintPath = "..\..\..\..\..\..\..\..\..\dotnet\NUnit2\bin\nunit.framework.dll"
-                />
-                <Reference
                     Name = "Apache.Avalon.Framework"
                     Project = "{A4DA9A13-FD5A-42A0-97C5-18CEDA5CB1A5}"
                     Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}"
+                />
+                <Reference
+                    Name = "nunit.framework"
+                    AssemblyName = "nunit.framework"
+                    HintPath = "..\..\..\..\..\..\dotnet\NUnit2\bin\nunit.framework.dll"
                 />
             </References>
         </Build>

---------------------------------------------------------------------
To unsubscribe, e-mail: cvs-unsubscribe@avalon.apache.org
For additional commands, e-mail: cvs-help@avalon.apache.org