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: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]