// Copyright 2004 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.Activation.Default { using System; using System.Collections; using System.Reflection; using Apache.Avalon.Framework; using Apache.Avalon.Composition.Model; using Apache.Avalon.Composition.Model.Default; using Apache.Avalon.DynamicProxy; /// /// Summary description for DefaultBlock. /// public class DefaultBlock : AbstractAppliance { //------------------------------------------------------------------- // immutable state //------------------------------------------------------------------- private object m_proxy; private IContainmentModel m_model; private ISystemContext m_system; private DefaultState m_commissioned = new DefaultState(); //------------------------------------------------------------------- // constructor //------------------------------------------------------------------- public DefaultBlock( ISystemContext system, IContainmentModel model ) : base( model ) { m_model = model; m_system = system; } //------------------------------------------------------------------- // Commissionable //------------------------------------------------------------------- /// /// Commission the appliance. /// public override void Commission() { lock( m_commissioned ) { if( m_commissioned.Enabled ) return; try { if (InterfaceTypes.Length != 0) { BlockInvocationHandler handler = new BlockInvocationHandler( this ); m_proxy = ProxyGenerator.CreateProxy( InterfaceTypes, handler ); } m_commissioned.Enabled = true; } catch( Exception e ) { String error = "Composite service establishment failure in block: " + this; throw new ApplianceRuntimeException( error, e ); } } } /// /// Decommission the appliance. Once an appliance is /// decommissioned it may be re-commissioned. /// public override void Decommission() { lock( m_commissioned ) { if( !m_commissioned.Enabled ) return; if( null != m_proxy ) { m_proxy = null; } m_commissioned.Enabled = false; } } //------------------------------------------------------------------- // Resolver //------------------------------------------------------------------- /// /// Resolve a object to a value. /// /// public override object Resolve() { if( !m_commissioned.Enabled ) { String error = "block.error.resolve.non-commission-state " + this.ToString(); throw new ApplicationException( error ); } return m_proxy; } /// /// Release an object /// /// the object to be released public override void Release( object instance ) { // ignore } //------------------------------------------------------------------- // implementation //------------------------------------------------------------------- /// /// Return the model backing the handler. /// protected internal IContainmentModel ContainmentModel { get { return m_model; } } private Type[] InterfaceTypes { get { IContainmentModel model = ContainmentModel; ArrayList list = new ArrayList(); IServiceModel[] services = model.ServiceModels; for( int i=0; i < services.Length; i++ ) { IServiceModel service = services[i]; list.Add( service.ServiceClass ); } return (Type[]) list.ToArray( typeof(Type) ); } } //------------------------------------------------------------------- // Object //------------------------------------------------------------------- public override String ToString() { return "block:" + ContainmentModel.QualifiedName; } } /// /// /// public class BlockInvocationHandler : IInvocationHandler { private DefaultBlock m_block; public BlockInvocationHandler( DefaultBlock block ) { if (block == null) { throw new ArgumentNullException("block"); } m_block = block; } #region IInvocationHandler Members public object Invoke(object proxy, MethodBase method, params object[] arguments) { IContainmentModel model = m_block.ContainmentModel; Type targetType = method.DeclaringType; IServiceModel service = model.GetServiceModel( targetType ); if (service == null) { throw new ApplianceException("Unable to resolve an provider for the interface " + targetType); } IDeploymentModel provider = service.ServiceProvider; Object target = provider.Resolve(); Type[] parameters = new Type[arguments.Length]; for(int i=0; i < arguments.Length; i++ ) { parameters[i] = arguments[i].GetType(); } MethodInfo targetMethod = targetType.GetMethod( method.Name, parameters ); return targetMethod.Invoke( target, arguments ); } #endregion } }