svn commit: rev 37382 - in avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel: . Concerns Handler Handler/Default Interceptor Interceptor/Default MicroKernelTest MicroKernelTest/Components

[email protected] 2 Sep 2004 14:57:17 -0000
Newsgroups gmane.comp.jakarta.avalon.cvs
Message-ID <[email protected]>
Author: hammett
Date: Thu Sep  2 07:57:16 2004
New Revision: 37382

Added:
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/ComponentWrapperTestCase.cs
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Components/IStartableService.cs   (contents, props changed)
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Components/SimpleStartableComponent.cs   (contents, props changed)
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Components/SimpleStartableComponent2.cs   (contents, props changed)
Modified:
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/BaseKernel.cs
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Concerns/ConcernManager.cs
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/DefaultAvalonKernel.cs
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Handler/AbstractHandler.cs
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Handler/Default/SimpleHandler.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/Interceptor/Default/InterceptedComponent.cs
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/IInterceptedComponent.cs
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Apache.Avalon.Castle.MicroKernel.Test.csproj
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/BaseKernelTestCase.cs
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/ConcernManagerTestCase.cs
   avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/KernelEventsTestCase.cs
Log:
Improving test cases. Coverage is now in 87% of Microkernel code.

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	Thu Sep  2 07:57:16 2004
@@ -51,6 +51,8 @@
 
         protected Hashtable m_dependencyToSatisfy;
 
+		protected Hashtable m_proxy2ComponentWrapper;
+
         protected IHandlerFactory m_handlerFactory;
 
         protected IComponentModelBuilder m_componentModelBuilder;
@@ -68,6 +70,7 @@
             m_key2Handler = new Hashtable(CaseInsensitiveHashCodeProvider.Default, CaseInsensitiveComparer.Default);
             m_service2Key = new Hashtable();
             m_subsystems = new Hashtable();
+			m_proxy2ComponentWrapper = new Hashtable();
             m_handlerFactory = new SimpleHandlerFactory();
             m_dependencyToSatisfy = new Hashtable();
             m_componentModelBuilder = new DefaultComponentModelBuilder(this);
@@ -356,7 +359,17 @@
             // AddSubsystem( KernelConstants.EVENTS, new EventManager() );
         }
 
-        #region RaiseEvents 
+        #region RaiseEvents
+
+		protected virtual void RaiseDependencyEvent( Type service, IHandler handler )
+		{
+			DependencyListenerDelegate del = (DependencyListenerDelegate) m_dependencyToSatisfy[ service ];
+			
+			if ( del != null )
+			{
+				del( service, handler );
+			}
+		}
 
         protected virtual void RaiseComponentRegistered(IComponentModel model, String key, IHandler handler)
         {
@@ -422,9 +435,20 @@
             {
                 IComponentModel model = handler.ComponentModel;
                 String key = (String) m_service2Key[ model.Service ];
-                IInterceptedComponent wrapper = new InterceptedComponentWrapper( m_interceptedComponentBuilder /*, instance, model.Service*/ );
+                InterceptedComponentWrapper wrapper = 
+					new InterceptedComponentWrapper( m_interceptedComponentBuilder, instance, model.Service );
 
                 eventDelegate(model, key, handler, wrapper);
+
+				if (wrapper.IsProxiedCreated)
+				{
+					object proxy = wrapper.ProxiedInstance;
+					m_proxy2ComponentWrapper[ proxy ] = wrapper;
+
+					// From now on, the outside world will have 
+					// a proxy pointer, not the instance anymore.
+					instance = proxy;
+				}
             }
 
             return instance;
@@ -434,15 +458,23 @@
         {
             UnWrapDelegate eventDelegate = (UnWrapDelegate) m_events[ComponentUnWrapEvent];
 
+			// We can have a null wrapper here
+			InterceptedComponentWrapper wrapper = m_proxy2ComponentWrapper[ instance ] as InterceptedComponentWrapper;
+
+			if (wrapper != null)
+			{
+				m_proxy2ComponentWrapper.Remove( instance );
+			}
+
             if (eventDelegate != null)
             {
                 IComponentModel model = handler.ComponentModel;
                 String key = (String) m_service2Key[ model.Service ];
 
-                instance = eventDelegate(model, key, handler, instance);
+                eventDelegate(model, key, handler, wrapper);
             }
 
-            return instance;
+            return wrapper != null ? wrapper.Instance : instance;
         }
 
         /// <summary>
@@ -451,46 +483,91 @@
         internal class InterceptedComponentWrapper : IInterceptedComponent
         {
             private IInterceptedComponentBuilder m_interceptedComponentBuilder;
+			private IInterceptedComponent m_delegate;
+			private object m_instance;
+        	private Type m_service;
 
-            public InterceptedComponentWrapper( IInterceptedComponentBuilder interceptedComponentBuilder )
+        	public InterceptedComponentWrapper( IInterceptedComponentBuilder interceptedComponentBuilder, 
+				object instance, Type service )
             {
                 m_interceptedComponentBuilder = interceptedComponentBuilder;
+				m_instance = instance;
+				m_service = service;
             }
 
+			public object Instance
+			{
+				get { return m_instance; }
+			}
+
             public object ProxiedInstance
             {
-                get { throw new NotImplementedException(); }
+                get
+                {
+					EnsureDelegate();
+                	return m_delegate.ProxiedInstance;
+                }
             }
 
             public void Add(IInterceptor interceptor)
             {
-                throw new NotImplementedException();
-            }
+				EnsureDelegate();
+				m_delegate.Add(interceptor);
+			}
 
             public IInterceptor InterceptorChain
             {
-                get { throw new NotImplementedException(); }
-            }
+				get
+				{
+					EnsureDelegate();
+					return m_delegate.InterceptorChain;
+				}
+			}
+
+			public bool IsProxiedCreated
+			{
+				get { return m_delegate != null; }
+			}
+
+			private void EnsureDelegate()
+			{
+				if (m_delegate == null)
+				{
+					m_delegate = m_interceptedComponentBuilder.CreateInterceptedComponent( 
+						m_instance, m_service );
+				}
+			}
         }
 
         #endregion
 
         /// <summary>
         /// Starts the component if the activation policy for 
-        /// the component is 'Start'
+        /// the component is 'Start' and if the component's dependencies are satisfied.
         /// </summary>
         /// <param name="model">Component model</param>
         /// <param name="handler">Handler responsible for the component</param>
-        protected virtual void StartComponent(IComponentModel model, IHandler handler)
+        protected virtual void StartComponentIfPossible(IComponentModel model, IHandler handler)
         {
             if (model.ActivationPolicy == Activation.Start)
             {
-                object instance = handler.Resolve();
-
-                m_componentsInstances.Add(new PairHandlerComponent(handler, instance));
+				if (handler.ActualState == State.Valid)
+				{
+					StartComponent( handler );
+				}
+				else if (handler.ActualState == State.WaitingDependency)
+				{
+					handler.AddChangeStateListener( new ChangeStateListenerDelegate(StartComponent) );
+				}
             }
         }
 
+		protected virtual void StartComponent( IHandler handler )
+		{
+			object instance = handler.Resolve();
+			m_componentsInstances.Add(new PairHandlerComponent(handler, instance));
+		}
+
         private void OnModelConstructed(IComponentModel model, String key)
         {
             RaiseModelConstructed(model, key);
@@ -500,9 +577,11 @@
         {
             m_service2Key[ model.Service ] = key;
 
+			RaiseDependencyEvent( model.Service, handler );
+
             RaiseComponentRegistered(model, key, handler);
 
-            StartComponent( model, handler );
+            StartComponentIfPossible( model, handler );
         }
 
         private void OnComponentUnregistered(IComponentModel model, String key, IHandler handler)

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Concerns/ConcernManager.cs
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Concerns/ConcernManager.cs	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Concerns/ConcernManager.cs	Thu Sep  2 07:57:16 2004
@@ -28,9 +28,9 @@
 
 		private Type m_destructionConcern;
 
-		private ArrayList m_commissionConcerns = new ArrayList();
+		private IList m_commissionConcerns = new ArrayList();
 
-		private ArrayList m_decommissionConcerns = new ArrayList();
+		private IList m_decommissionConcerns = new ArrayList();
 
 		/// <summary>
 		/// 

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/DefaultAvalonKernel.cs
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/DefaultAvalonKernel.cs	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/DefaultAvalonKernel.cs	Thu Sep  2 07:57:16 2004
@@ -17,10 +17,8 @@
 	using System;
 
 	using Apache.Avalon.Castle.MicroKernel.Concerns;
-	using Apache.Avalon.Castle.MicroKernel.Model;
 	using Apache.Avalon.Castle.MicroKernel.Subsystems.Configuration.Default;
 	using Apache.Avalon.Castle.MicroKernel.Subsystems.Logger.Default;
-	using Apache.Avalon.Castle.MicroKernel.Subsystems.Context.Default;
 
 	/// <summary>
 	/// Specialization of BaseKernel to adhere to Avalon 

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	Thu Sep  2 07:57:16 2004
@@ -24,11 +24,15 @@
     /// </summary>
     public abstract class AbstractHandler : IHandler
     {
-        protected IKernel m_kernel;
+		private State m_state = State.Valid;
+		
+		private IList m_instances = new ArrayList();
 
-        protected IComponentModel m_componentModel;
+		private Delegate m_changeStateListener;
+
+		protected IKernel m_kernel;
 
-        protected State m_state = State.Valid;
+        protected IComponentModel m_componentModel;
 
         protected IList m_dependencies = new ArrayList();
 
@@ -36,8 +40,6 @@
 
         protected ILifestyleManager m_lifestyleManager;
 
-        private IList m_instances = new ArrayList();
-
         /// <summary>
         /// 
         /// </summary>
@@ -61,6 +63,22 @@
             get { return m_componentModel; }
         }
 
+		/// <summary>
+		/// 
+		/// </summary>
+		/// <param name="changeStateDelegate"></param>
+		public void AddChangeStateListener( ChangeStateListenerDelegate changeStateDelegate )
+		{
+			if (m_changeStateListener == null)
+			{
+				m_changeStateListener = changeStateDelegate;
+			}
+			else
+			{
+				m_changeStateListener = Delegate.Combine(m_changeStateListener, changeStateDelegate);
+			}
+		}
+
         public virtual object Resolve()
         {
             if (ActualState == State.WaitingDependency)
@@ -110,6 +128,22 @@
         }
 
         #endregion
+
+		protected virtual void SetNewState( State state )
+		{
+			m_state = state;
+
+			RaiseChangeStateEvent();
+		}
+
+		protected virtual void RaiseChangeStateEvent()
+		{
+			if ( m_changeStateListener != null )
+			{
+				ChangeStateListenerDelegate del = (ChangeStateListenerDelegate) m_changeStateListener;
+				del( this );
+			}
+		}
 
         protected virtual void RegisterInstance(object instance)
         {

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Handler/Default/SimpleHandler.cs
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Handler/Default/SimpleHandler.cs	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Handler/Default/SimpleHandler.cs	Thu Sep  2 07:57:16 2004
@@ -63,9 +63,9 @@
 			}
 			else
 			{
-				// This is handler is considered invalid
+				// This handler is considered invalid
 				// until dependencies are satisfied
-				m_state = State.WaitingDependency;
+				SetNewState( State.WaitingDependency );
 				m_dependencies.Add( service );
 						
 				// Register ourself in the kernel
@@ -91,7 +91,7 @@
 
 			if (m_dependencies.Count == 0)
 			{
-				m_state = State.Valid;
+				SetNewState(State.Valid);
 			}
 		}
 

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	Thu Sep  2 07:57:16 2004
@@ -14,7 +14,11 @@
 
 namespace Apache.Avalon.Castle.MicroKernel
 {
-    using Apache.Avalon.Castle.MicroKernel.Model;
+	using System;
+	
+	using Apache.Avalon.Castle.MicroKernel.Model;
+
+	public delegate void ChangeStateListenerDelegate( IHandler handler );
 
 	/// <summary>
 	/// Summary description for IHandler.
@@ -43,5 +47,11 @@
         /// 
         /// </summary>
 	    IComponentModel ComponentModel { get; }
+
+		/// <summary>
+		/// 
+		/// </summary>
+		/// <param name="changeStateDelegate"></param>
+		void AddChangeStateListener( ChangeStateListenerDelegate changeStateDelegate );
 	}
 }

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	Thu Sep  2 07:57:16 2004
@@ -23,7 +23,7 @@
 
 	public delegate void WrapDelegate( IComponentModel model, String key, IHandler handler, IInterceptedComponent interceptedComponent );
 
-    public delegate object UnWrapDelegate( IComponentModel model, String key, IHandler handler, object instance );
+    public delegate void UnWrapDelegate( IComponentModel model, String key, IHandler handler, IInterceptedComponent interceptedComponent );
 
 	public delegate void ComponentInstanceDelegate( IComponentModel model, String key, IHandler handler, object instance );
 

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/Default/InterceptedComponent.cs
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/Default/InterceptedComponent.cs	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/Default/InterceptedComponent.cs	Thu Sep  2 07:57:16 2004
@@ -47,6 +47,8 @@
 			m_proxy = proxy;
 		}
 
+		#region IInterceptedComponent Members
+
 		/// <summary>
 		/// Returns the component instance, non-proxied.
 		/// </summary>
@@ -54,8 +56,6 @@
 		{
 			get { return m_instance; }
 		}
-
-		#region IInterceptedComponent Members
 
 		/// <summary>
 		/// Add the interceptor in the argument as the first interceptor

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/IInterceptedComponent.cs
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/IInterceptedComponent.cs	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/Interceptor/IInterceptedComponent.cs	Thu Sep  2 07:57:16 2004
@@ -21,6 +21,8 @@
 	/// </summary>
 	public interface IInterceptedComponent
 	{
+		object Instance { get; }
+
 		object ProxiedInstance { get; }
 
 		void Add( IInterceptor interceptor );

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	Thu Sep  2 07:57:16 2004
@@ -119,6 +119,11 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "ComponentWrapperTestCase.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "ConcernManagerTestCase.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -239,6 +244,11 @@
                     BuildAction = "Compile"
                 />
                 <File
+                    RelPath = "Components\IStartableService.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
                     RelPath = "Components\SimpleCustomerManager.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
@@ -260,6 +270,16 @@
                 />
                 <File
                     RelPath = "Components\SimpleSpamService.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Components\SimpleStartableComponent.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Components\SimpleStartableComponent2.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
                 />

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/BaseKernelTestCase.cs
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/BaseKernelTestCase.cs	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/BaseKernelTestCase.cs	Thu Sep  2 07:57:16 2004
@@ -14,8 +14,11 @@
 
 namespace Apache.Avalon.Castle.MicroKernel.Test
 {
+	using System;
+
 	using NUnit.Framework;
 
+	using Apache.Avalon.Framework;
 	using Apache.Avalon.Castle.MicroKernel;
 	using Apache.Avalon.Castle.MicroKernel.Test.Components;
 
@@ -25,6 +28,20 @@
 	[TestFixture]
 	public class BaseKernelTestCase : Assertion
 	{
+		IKernel m_container;
+
+		[SetUp]
+		public void Init()
+		{
+			m_container = new BaseKernel();
+		}
+
+		[TearDown]
+		public void Terminate()
+		{
+			ContainerUtil.Dispose( m_container );
+		}
+
 		/// <summary>
 		/// Just a simple Service resolution.
 		/// No concerns or aspects involved.
@@ -32,10 +49,9 @@
 		[Test]
 		public void SimpleUsage()
 		{
-			BaseKernel container = new BaseKernel();
-			container.AddComponent( "a", typeof(IMailService), typeof(SimpleMailService) );
+			m_container.AddComponent( "a", typeof(IMailService), typeof(SimpleMailService) );
 
-			IHandler handler = container[ "a" ];
+			IHandler handler = m_container[ "a" ];
 
 			IMailService service = handler.Resolve() as IMailService;
 
@@ -46,31 +62,67 @@
 			handler.Release( service );
 		}
 
+		[Test]
+		public void InvalidComponent()
+		{
+			try
+			{
+				m_container.AddComponent( "a", typeof(IMailService), typeof(String) );
+				Fail("Should not allow a type which not implements the specified service.");
+			}
+			catch(ArgumentException)
+			{
+				// Expected
+			}
+		}
+
         [Test]
         public void AddAndRemove()
         {
-            BaseKernel container = new BaseKernel();
-            container.AddComponent( "a", typeof(IMailService), typeof(SimpleMailService) );
+            m_container.AddComponent( "a", typeof(IMailService), typeof(SimpleMailService) );
 
-            AssertNotNull( container.GetHandlerForService( typeof(IMailService) ) );
-            AssertNotNull( container[ "a" ] );
+            AssertNotNull( m_container.GetHandlerForService( typeof(IMailService) ) );
+            AssertNotNull( m_container[ "a" ] );
 
-            AssertNull( container.GetHandlerForService( typeof(IMailMarketingService) ) );
-            AssertNull( container[ "b" ] );
+            AssertNull( m_container.GetHandlerForService( typeof(IMailMarketingService) ) );
+            AssertNull( m_container[ "b" ] );
 
-            container.RemoveComponent( "a" );
+            m_container.RemoveComponent( "a" );
 
-            AssertNull( container.GetHandlerForService( typeof(IMailService) ) );
-            AssertNull( container[ "a" ] );
+            AssertNull( m_container.GetHandlerForService( typeof(IMailService) ) );
+            AssertNull( m_container[ "a" ] );
         }
 
 		[Test]
+		public void StartableComponent()
+		{
+			SimpleStartableComponent.Constructed = false;
+
+			m_container.AddComponent( "a", typeof(IStartableService), typeof(SimpleStartableComponent) );
+
+			Assert( SimpleStartableComponent.Constructed );
+		}
+
+		[Test]
+		public void StartableComponentWithDependencies()
+		{
+			SimpleStartableComponent.Constructed = false;
+
+			m_container.AddComponent( "a", typeof(IStartableService), typeof(SimpleStartableComponent2) );
+
+			Assert( !SimpleStartableComponent.Constructed );
+
+			m_container.AddComponent( "b", typeof(IMailService), typeof(SimpleMailService) );
+
+			Assert( SimpleStartableComponent.Constructed );
+		}
+
+		[Test]
 		public void ComponentDependingOnLogger()
 		{
-			BaseKernel container = new BaseKernel();
-			container.AddComponent( "a", typeof(IMailService), typeof(SimpleMailServiceWithLogger) );
+			m_container.AddComponent( "a", typeof(IMailService), typeof(SimpleMailServiceWithLogger) );
 
-			IHandler handler = container[ "a" ];
+			IHandler handler = m_container[ "a" ];
 
 			IMailService service = handler.Resolve() as IMailService;
 
@@ -84,20 +136,19 @@
 
 		/*
 		[Test]
-		public void FacilityEvents()
+		public void FacilityLifecycle()
 		{
-			BaseKernel container = new BaseKernel();
 			MockFacility facility = new MockFacility();
 
-			container.RegisterFacility( facility );
+			m_container.RegisterFacility( facility );
 
 			Assert( facility.OnInitCalled );
 
-			container.AddComponent( "a", typeof(IMailService), typeof(SimpleMailServiceWithLogger) );
+			m_container.AddComponent( "a", typeof(IMailService), typeof(SimpleMailServiceWithLogger) );
 
 			Assert( facility.ComponentAddedCalled );
 
-			IHandler handler = container[ "a" ];
+			IHandler handler = m_container[ "a" ];
 
 			IMailService service = handler.Resolve() as IMailService;
 
@@ -115,7 +166,6 @@
 
 		public class MockFacility : IContainerFacility
 		{
-			
 		}
 		*/
 	}

Added: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/ComponentWrapperTestCase.cs
==============================================================================
--- (empty file)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/ComponentWrapperTestCase.cs	Thu Sep  2 07:57:16 2004
@@ -0,0 +1,85 @@
+// 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
+{
+	using System;
+
+	using NUnit.Framework;
+
+	using Apache.Avalon.Castle.MicroKernel.Interceptor;
+	using Apache.Avalon.Castle.MicroKernel.Model;
+	using Apache.Avalon.Castle.MicroKernel.Test.Components;
+
+	/// <summary>
+	/// Summary description for ComponentWrapperTestCase.
+	/// </summary>
+	[TestFixture]
+	public class ComponentWrapperTestCase : Assertion
+	{
+		private MyInterceptor m_interceptor = new MyInterceptor();
+
+		[Test]
+		public void WrappingComponent()
+		{
+			IKernel container = new BaseKernel();
+
+			container.ComponentWrap += new WrapDelegate(ComponentWrap);
+			container.ComponentUnWrap += new UnWrapDelegate(ComponentUnWrap);
+
+			container.AddComponent( "a", typeof(IMailService), typeof(SimpleMailService) );
+
+			IHandler handler = container[ "a" ];
+
+			IMailService service = handler.Resolve() as IMailService;
+
+			service.Send("hammett at apache dot org", "johndoe at yahoo dot org", "Aloha!", "What's up?");
+			Assert( m_interceptor.InterceptorInvoked );
+
+			handler.Release( service );
+		}
+
+		private void ComponentWrap(IComponentModel model, string key, IHandler handler, IInterceptedComponent interceptedComponent)
+		{
+			interceptedComponent.Add( m_interceptor );
+
+			AssertNotNull( interceptedComponent.Instance );
+			AssertNotNull( interceptedComponent.ProxiedInstance );
+			AssertNotNull( interceptedComponent.InterceptorChain );
+			Assert( interceptedComponent.Instance != interceptedComponent.ProxiedInstance );
+		}
+
+		private void ComponentUnWrap(IComponentModel model, string key, IHandler handler, IInterceptedComponent interceptedComponent)
+		{
+			AssertNotNull( interceptedComponent );
+		}
+
+		internal class MyInterceptor : AbstractInterceptor
+		{
+			private bool m_interceptorInvoked = false;
+
+			public bool InterceptorInvoked
+			{
+				get { return m_interceptorInvoked; }
+			}
+
+			public override object Process(object instance, System.Reflection.MethodInfo method, params object[] arguments)
+			{
+				m_interceptorInvoked = true;
+
+				return base.Process (instance, method, arguments);
+			}
+		}
+	}
+}

Added: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Components/IStartableService.cs
==============================================================================
--- (empty file)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Components/IStartableService.cs	Thu Sep  2 07:57:16 2004
@@ -0,0 +1,26 @@
+// 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.Components
+{
+	using System;
+
+	/// <summary>
+	/// Summary description for IStartableService.
+	/// </summary>
+	public interface IStartableService
+	{
+		void DoSomeUsefulWork();
+	}
+}

Added: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Components/SimpleStartableComponent.cs
==============================================================================
--- (empty file)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Components/SimpleStartableComponent.cs	Thu Sep  2 07:57:16 2004
@@ -0,0 +1,48 @@
+ // 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.Components
+{
+	using System;
+
+	using Apache.Avalon.Framework;
+
+	/// <summary>
+	/// Summary description for SimpleStartableComponent.
+	/// </summary>
+	[AvalonComponent("StartableComponent", Lifestyle.Singleton, Activation.Start)]
+	public class SimpleStartableComponent : IStartableService
+	{
+		private static bool m_constructed = false;
+
+		public SimpleStartableComponent()
+		{
+			m_constructed = true;
+		}
+
+		public static bool Constructed
+		{
+			get { return m_constructed; }
+			set { m_constructed = value; }
+		}
+
+		#region IStartableService Members
+
+		public void DoSomeUsefulWork()
+		{
+		}
+
+		#endregion
+	}
+}
\ No newline at end of file

Added: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Components/SimpleStartableComponent2.cs
==============================================================================
--- (empty file)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/Components/SimpleStartableComponent2.cs	Thu Sep  2 07:57:16 2004
@@ -0,0 +1,31 @@
+// 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.Components
+{
+	using System;
+
+	using Apache.Avalon.Framework;
+
+	/// <summary>
+	/// Summary description for SimpleStartableComponent2.
+	/// </summary>
+	[AvalonComponent("StartableComponent2", Lifestyle.Singleton, Activation.Start)]
+	public class SimpleStartableComponent2 : SimpleStartableComponent
+	{
+		public SimpleStartableComponent2( IMailService service )
+		{
+		}
+	}
+}

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/ConcernManagerTestCase.cs
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/ConcernManagerTestCase.cs	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/ConcernManagerTestCase.cs	Thu Sep  2 07:57:16 2004
@@ -43,6 +43,38 @@
 		}
 
 		[Test]
+		public void InvalidConcern()
+		{
+			ConcernManager manager = new ConcernManager();
+			
+			try
+			{
+				manager.Add( typeof(String) );
+				Fail("Could not allow a type which is not a concern");
+			}
+			catch(ArgumentException)
+			{
+				// Expected
+			}
+		}
+
+		[Test]
+		public void GetDefaultCommissionConcerns()
+		{
+			ConcernManager manager = new ConcernManager();
+			AssertNotNull( manager.CommissionConcerns );
+			AssertEquals( 6, manager.CommissionConcerns.Count );
+		}
+
+		[Test]
+		public void GetDefaultDecommissionConcerns()
+		{
+			ConcernManager manager = new ConcernManager();
+			AssertNotNull( manager.DecommissionConcerns );
+			AssertEquals( 1, manager.DecommissionConcerns.Count );
+		}
+
+		[Test]
 		public void GetDefaultCommissionChain()
 		{
 			ConcernManager manager = new ConcernManager();

Modified: avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/KernelEventsTestCase.cs
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/KernelEventsTestCase.cs	(original)
+++ avalon/trunk/central/laboratory/avalon-net/Castle/MicroKernel/MicroKernelTest/KernelEventsTestCase.cs	Thu Sep  2 07:57:16 2004
@@ -20,7 +20,8 @@
 
     using Apache.Avalon.Castle.MicroKernel;
     using Apache.Avalon.Castle.MicroKernel.Model;
-    using Apache.Avalon.Castle.MicroKernel.Test.Components;
+	using Apache.Avalon.Castle.MicroKernel.Interceptor;
+	using Apache.Avalon.Castle.MicroKernel.Test.Components;
 
 	/// <summary>
 	/// Summary description for KernelEventsTestCase.
@@ -175,16 +176,14 @@
             m_wrap = true;
         }
 
-        private object ComponentUnWrap(IComponentModel model, String key, IHandler handler, object instance)
+        private void ComponentUnWrap(IComponentModel model, String key, IHandler handler, IInterceptedComponent interceptedComponent)
         {
             AssertNotNull( model );
             AssertNotNull( key );
             AssertNotNull( handler );
-            AssertNotNull( instance );
+            AssertNull( interceptedComponent );
 
             m_unwrap = true;
-
-            return instance;
         }
 
         private void ComponentReady(IComponentModel model, String key, IHandler handler, object instance)