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