// 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; using System.Collections; using System.ComponentModel; using Apache.Avalon.Castle.MicroKernel.Model; using Apache.Avalon.Castle.MicroKernel.Interceptor; using Apache.Avalon.Castle.MicroKernel.Interceptor.Default; /// /// Implements the basic functionality. /// public abstract class AbstractKernelEvents : IKernelEvents { private static readonly object ComponentRegisteredEvent = new object(); private static readonly object ComponentUnregisteredEvent = new object(); private static readonly object ComponentWrapEvent = new object(); private static readonly object ComponentUnWrapEvent = new object(); private static readonly object ComponentReadyEvent = new object(); private static readonly object ComponentReleasedEvent = new object(); private static readonly object ComponentModelConstructedEvent = new object(); private EventHandlerList m_events; protected Hashtable m_proxy2ComponentWrapper; protected Hashtable m_service2Key; protected Hashtable m_dependencyToSatisfy; protected IInterceptedComponentBuilder m_interceptedComponentBuilder; public AbstractKernelEvents() { m_events = new EventHandlerList(); m_service2Key = new Hashtable(); m_dependencyToSatisfy = new Hashtable(); m_proxy2ComponentWrapper = new Hashtable(); InterceptedComponentBuilder = new DefaultInterceptedComponentBuilder(); } #region IKernelEvents /// /// Pending /// /// public event ComponentDataDelegate ComponentRegistered { add { m_events.AddHandler(ComponentRegisteredEvent, value); } remove { m_events.RemoveHandler(ComponentRegisteredEvent, value); } } /// /// Pending /// /// public event ComponentDataDelegate ComponentUnregistered { add { m_events.AddHandler(ComponentUnregisteredEvent, value); } remove { m_events.RemoveHandler(ComponentUnregisteredEvent, value); } } /// /// Pending /// /// public event WrapDelegate ComponentWrap { add { m_events.AddHandler(ComponentWrapEvent, value); } remove { m_events.RemoveHandler(ComponentWrapEvent, value); } } /// /// Pending /// /// public event WrapDelegate ComponentUnWrap { add { m_events.AddHandler(ComponentUnWrapEvent, value); } remove { m_events.RemoveHandler(ComponentUnWrapEvent, value); } } /// /// Pending /// /// public event ComponentInstanceDelegate ComponentReady { add { m_events.AddHandler(ComponentReadyEvent, value); } remove { m_events.RemoveHandler(ComponentReadyEvent, value); } } /// /// Pending /// /// public event ComponentInstanceDelegate ComponentReleased { add { m_events.AddHandler(ComponentReleasedEvent, value); } remove { m_events.RemoveHandler(ComponentReleasedEvent, value); } } /// /// Pending /// /// public event ComponentModelDelegate ComponentModelConstructed { add { m_events.AddHandler(ComponentModelConstructedEvent, value); } remove { m_events.RemoveHandler(ComponentModelConstructedEvent, value); } } public virtual void RaiseComponentReadyEvent(IHandler handler, object instance) { ComponentInstanceDelegate eventDelegate = (ComponentInstanceDelegate) m_events[ComponentReadyEvent]; if (eventDelegate != null) { IComponentModel model = handler.ComponentModel; String key = (String) m_service2Key[model.Service]; eventDelegate(model, key, handler, instance); } } public virtual void RaiseComponentReleasedEvent(IHandler handler, object instance) { ComponentInstanceDelegate eventDelegate = (ComponentInstanceDelegate) m_events[ComponentReleasedEvent]; if (eventDelegate != null) { IComponentModel model = handler.ComponentModel; String key = (String) m_service2Key[model.Service]; eventDelegate(model, key, handler, instance); } } public virtual object RaiseWrapEvent(IHandler handler, object instance) { WrapDelegate eventDelegate = (WrapDelegate) m_events[ComponentWrapEvent]; if (eventDelegate != null) { IComponentModel model = handler.ComponentModel; String key = (String) m_service2Key[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; } public virtual object RaiseUnWrapEvent(IHandler handler, object instance) { WrapDelegate eventDelegate = (WrapDelegate) 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]; eventDelegate(model, key, handler, wrapper); } return wrapper != null ? wrapper.Instance : instance; } #endregion 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) { ComponentDataDelegate eventDelegate = (ComponentDataDelegate) m_events[ComponentRegisteredEvent]; if (eventDelegate != null) { eventDelegate(model, key, handler); } } protected virtual void RaiseComponentUnregistered(IComponentModel model, String key, IHandler handler) { ComponentDataDelegate eventDelegate = (ComponentDataDelegate) m_events[ComponentUnregisteredEvent]; if (eventDelegate != null) { eventDelegate(model, key, handler); } } protected virtual void RaiseModelConstructed(IComponentModel model, String key) { ComponentModelDelegate eventDelegate = (ComponentModelDelegate) m_events[ComponentModelConstructedEvent]; if (eventDelegate != null) { eventDelegate(model, key); } } public virtual IInterceptedComponentBuilder InterceptedComponentBuilder { get { return m_interceptedComponentBuilder; } set { AssertUtil.ArgumentNotNull(value, "value"); m_interceptedComponentBuilder = value; } } /// /// /// public class InterceptedComponentWrapper : IInterceptedComponent { private IInterceptedComponentBuilder m_interceptedComponentBuilder; private IInterceptedComponent m_delegate; private object m_instance; private Type m_service; 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 { EnsureDelegate(); return m_delegate.ProxiedInstance; } } public void Add(IInterceptor interceptor) { EnsureDelegate(); m_delegate.Add(interceptor); } public IInterceptor InterceptorChain { 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); } } } } }