hammett 2004/03/05 19:29:21 Added: avalon-net/DynamicProxy Apache.Avalon.DynamicProxy.csproj AssemblyInfo.cs DynamicProxy.sln IInvocationHandler.cs ProxyGenerator.cs avalon-net/DynamicProxy/DynamicProxyTest Apache.Avalon.DynamicProxy.Test.csproj AssemblyInfo.cs ProxyGeneratorTestCase.cs Log: Simple dynamic proxy (java like proxies) for CLI (Mono/.Net) Revision Changes Path 1.1 avalon-sandbox/avalon-net/DynamicProxy/Apache.Avalon.DynamicProxy.csproj Index: Apache.Avalon.DynamicProxy.csproj =================================================================== <VisualStudioProject> <CSHARP ProjectType = "Local" ProductVersion = "7.10.3077" SchemaVersion = "2.0" ProjectGuid = "{70EE6AF2-1F6D-4CC5-A1B2-C3182F035F67}" > <Build> <Settings ApplicationIcon = "" AssemblyKeyContainerName = "" AssemblyName = "Apache.Avalon.DynamicProxy" AssemblyOriginatorKeyFile = "" DefaultClientScript = "JScript" DefaultHTMLPageLayout = "Grid" DefaultTargetSchema = "IE50" DelaySign = "false" OutputType = "Library" PreBuildEvent = "" PostBuildEvent = "" RootNamespace = "Apache.Avalon.DynamicProxy" RunPostBuildEvent = "OnBuildSuccess" StartupObject = "" > <Config Name = "Debug" AllowUnsafeBlocks = "false" BaseAddress = "285212672" CheckForOverflowUnderflow = "false" ConfigurationOverrideFile = "" DefineConstants = "DEBUG;TRACE" DocumentationFile = "" DebugSymbols = "true" FileAlignment = "4096" IncrementalBuild = "false" NoStdLib = "false" NoWarn = "" Optimize = "false" OutputPath = "bin\Debug\" RegisterForComInterop = "false" RemoveIntegerChecks = "false" TreatWarningsAsErrors = "false" WarningLevel = "4" /> <Config Name = "Release" AllowUnsafeBlocks = "false" BaseAddress = "285212672" CheckForOverflowUnderflow = "false" ConfigurationOverrideFile = "" DefineConstants = "TRACE" DocumentationFile = "" DebugSymbols = "false" FileAlignment = "4096" IncrementalBuild = "false" NoStdLib = "false" NoWarn = "" Optimize = "true" OutputPath = "bin\Release\" RegisterForComInterop = "false" RemoveIntegerChecks = "false" TreatWarningsAsErrors = "false" WarningLevel = "4" /> </Settings> <References> <Reference Name = "System" AssemblyName = "System" HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll" /> <Reference Name = "System.Data" AssemblyName = "System.Data" HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Data.dll" /> <Reference Name = "System.XML" AssemblyName = "System.Xml" HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll" /> </References> </Build> <Files> <Include> <File RelPath = "AssemblyInfo.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "IInvocationHandler.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "ProxyGenerator.cs" SubType = "Code" BuildAction = "Compile" /> </Include> </Files> </CSHARP> </VisualStudioProject> 1.1 avalon-sandbox/avalon-net/DynamicProxy/AssemblyInfo.cs Index: AssemblyInfo.cs =================================================================== // 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. using System.Reflection; using System.Runtime.CompilerServices; [assembly: AssemblyTitle("Avalon DynamicProxy")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("The Apache Software Foundation")] [assembly: AssemblyProduct("Avalon DynamicProxy")] [assembly: AssemblyCopyright("Copyright (c) 2004 The Apache Software Foundation")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: AssemblyVersion("1.0.0.0")] #if STRONG [assembly: AssemblyDelaySign(false)] [assembly: AssemblyKeyFile("../../../../ApacheAvalon.snk")] [assembly: AssemblyKeyName("")] #endif 1.1 avalon-sandbox/avalon-net/DynamicProxy/DynamicProxy.sln Index: DynamicProxy.sln =================================================================== Microsoft Visual Studio Solution File, Format Version 8.00 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Avalon.DynamicProxy", "Apache.Avalon.DynamicProxy.csproj", "{70EE6AF2-1F6D-4CC5-A1B2-C3182F035F67}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Apache.Avalon.DynamicProxy.Test", "DynamicProxyTest\Apache.Avalon.DynamicProxy.Test.csproj", "{EF89321E-FB2A-41B6-85B3-794D50A55CF1}" ProjectSection(ProjectDependencies) = postProject EndProjectSection EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {70EE6AF2-1F6D-4CC5-A1B2-C3182F035F67}.Debug.ActiveCfg = Debug|.NET {70EE6AF2-1F6D-4CC5-A1B2-C3182F035F67}.Debug.Build.0 = Debug|.NET {70EE6AF2-1F6D-4CC5-A1B2-C3182F035F67}.Release.ActiveCfg = Release|.NET {70EE6AF2-1F6D-4CC5-A1B2-C3182F035F67}.Release.Build.0 = Release|.NET {EF89321E-FB2A-41B6-85B3-794D50A55CF1}.Debug.ActiveCfg = Debug|.NET {EF89321E-FB2A-41B6-85B3-794D50A55CF1}.Debug.Build.0 = Debug|.NET {EF89321E-FB2A-41B6-85B3-794D50A55CF1}.Release.ActiveCfg = Release|.NET {EF89321E-FB2A-41B6-85B3-794D50A55CF1}.Release.Build.0 = Release|.NET EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection GlobalSection(ExtensibilityAddIns) = postSolution EndGlobalSection EndGlobal 1.1 avalon-sandbox/avalon-net/DynamicProxy/IInvocationHandler.cs Index: IInvocationHandler.cs =================================================================== // 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.DynamicProxy { using System; using System.Reflection; /// <summary> /// Defines the handler that will receive all methods /// invoked on the proxy object. /// </summary> public interface IInvocationHandler { /// <summary> /// Implementation should invoke the method on the real object. /// </summary> /// <param name="proxy">proxy instance</param> /// <param name="method"><see cref="System.Reflection.MethodBase"/> being invoked.</param> /// <param name="arguments">Arguments of method - if any</param> /// <returns>Should return the result of method invocation</returns> object Invoke(object proxy, MethodBase method, params object[] arguments); } } 1.1 avalon-sandbox/avalon-net/DynamicProxy/ProxyGenerator.cs Index: ProxyGenerator.cs =================================================================== // 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.DynamicProxy { using System; using System.Reflection; using System.Reflection.Emit; /// <summary> /// Generates a Java style proxy. This overrides the .Net proxy requirements /// that forces one to extend MarshalByRefObject or (for a different purpose) /// ContextBoundObject to have a Proxiable class. /// </summary> /// <remarks> /// The <see cref="ProxyGenerator"/> should be used to generate a class /// implementing the specified interfaces. The class implementation will /// only call the internal <see cref="IInvocationHandler"/> instance. /// </remarks> /// <example> /// <code> /// MyInvocationHandler handler = ... /// IInterfaceExposed proxy = /// ProxyGenerator.CreateProxy( new Type[] { typeof(IInterfaceExposed) }, handler ); /// </code> /// </example> public class ProxyGenerator { /// <summary> /// Private construtor /// </summary> private ProxyGenerator() { } /// <summary> /// Generates a proxy implementing all the specified interfaces and /// redirecting method invocations to the specifed handler. /// </summary> /// <param name="interfaces">Array of interfaces to be implemented</param> /// <param name="handler">instance of <see cref="IInvocationHandler"/></param> /// <returns>Proxy instance</returns> public static object CreateProxy(Type[] interfaces, IInvocationHandler handler) { if (interfaces == null) { throw new ArgumentNullException("interfaces"); } if (handler == null) { throw new ArgumentNullException("handler"); } AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = "DynamicAssemblyProxyGen"; AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly( assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule( assemblyName.Name, true ); TypeBuilder typeBuilder = moduleBuilder.DefineType( "ProxyType", TypeAttributes.Public|TypeAttributes.Class, null, interfaces); foreach(Type inter in interfaces) { GenerateInterfaceImplementation( typeBuilder, inter ); } Type generatedType = typeBuilder.CreateType(); return Activator.CreateInstance( generatedType, new object[] { handler } ); } /// <summary> /// Iterates over the interfaces and generate implementation /// for each method in it. /// </summary> /// <param name="typeBuilder"><see cref="TypeBuilder"/> being constructed.</param> /// <param name="inter">Interface type</param> private static void GenerateInterfaceImplementation( TypeBuilder typeBuilder, Type inter ) { if (!inter.IsInterface) { throw new ArgumentException("Type array expects interfaces only."); } FieldBuilder handlerField = GenerateField( typeBuilder ); ConstructorBuilder constr = GenerateConstructor( typeBuilder, handlerField ); PropertyInfo[] properties = inter.GetProperties(); PropertyBuilder[] propertiesBuilder = new PropertyBuilder[properties.Length]; for(int i=0; i < properties.Length; i++) { GeneratePropertyImplementation( typeBuilder, properties[i], ref propertiesBuilder[i] ); } MethodInfo[] methods = inter.GetMethods(); foreach(MethodInfo method in methods) { GenerateMethodImplementation( typeBuilder, method, propertiesBuilder, handlerField, inter ); } } /// <summary> /// Generates a public field holding the <see cref="IInvocationHandler"/> /// </summary> /// <param name="typeBuilder"><see cref="TypeBuilder"/> being constructed.</param> /// <returns><see cref="FieldBuilder"/> instance</returns> private static FieldBuilder GenerateField( TypeBuilder typeBuilder ) { return typeBuilder.DefineField( "handler", typeof(IInvocationHandler), FieldAttributes.Public ); } /// <summary> /// Generates one public constructor receiving /// the <see cref="IInvocationHandler"/> instance. /// </summary> /// <param name="typeBuilder"><see cref="TypeBuilder"/> being constructed.</param> /// <param name="handlerField"><see cref="FieldBuilder"/> instance representing the handler field</param> /// <returns><see cref="ConstructorBuilder"/> instance</returns> private static ConstructorBuilder GenerateConstructor( TypeBuilder typeBuilder, FieldBuilder handlerField ) { ConstructorBuilder consBuilder = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(IInvocationHandler) } ); ILGenerator ilGenerator = consBuilder.GetILGenerator(); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Call, typeof(Object).GetConstructor(new Type[0])); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldarg_1); ilGenerator.Emit(OpCodes.Stfld, handlerField); ilGenerator.Emit(OpCodes.Ret); return consBuilder; } /// <summary> /// Generate property implementation /// </summary> /// <param name="typeBuilder"><see cref="TypeBuilder"/> being constructed.</param> /// <param name="property"></param> /// <param name="propertyBuilder"></param> private static void GeneratePropertyImplementation( TypeBuilder typeBuilder, PropertyInfo property, ref PropertyBuilder propertyBuilder ) { propertyBuilder = typeBuilder.DefineProperty( property.Name, property.Attributes, property.PropertyType, null); } /// <summary> /// Generates implementation for each method. /// </summary> /// <param name="typeBuilder"><see cref="TypeBuilder"/> being constructed.</param> /// <param name="method"></param> /// <param name="properties"></param> private static void GenerateMethodImplementation( TypeBuilder typeBuilder, MethodInfo method, PropertyBuilder[] properties, FieldBuilder handlerField, Type inter ) { ParameterInfo[] parameterInfo = method.GetParameters(); System.Type[] parameters = new System.Type[parameterInfo.Length]; for (int i=0; i<parameterInfo.Length; i++) { parameters[i] = parameterInfo[i].ParameterType; } MethodAttributes atts = MethodAttributes.Public|MethodAttributes.Virtual; if ( method.Name.StartsWith("set_") || method.Name.StartsWith("get_") ) { atts = MethodAttributes.Public|MethodAttributes.SpecialName|MethodAttributes.Virtual; } MethodBuilder methodBuilder = typeBuilder.DefineMethod( method.Name, atts, CallingConventions.Standard, method.ReturnType, parameters ); if ( method.Name.StartsWith("set_") || method.Name.StartsWith("get_") ) { foreach( PropertyBuilder property in properties ) { if (property == null) { break; } if (!property.Name.Equals( method.Name.Substring(4) )) { continue; } if ( methodBuilder.Name.StartsWith("set_") ) { property.SetSetMethod( methodBuilder ); break; } else { property.SetGetMethod( methodBuilder ); break; } } } WriteILForMethod( methodBuilder, parameters, handlerField ); } /// <summary> /// Writes the stack for the method implementation. This /// method generates the IL stack for property get/set method and /// ordinary methods. /// </summary> /// <remarks> /// The method implementation would be as simple as: /// <code> /// public void SomeMethod( int parameter ) /// { /// MethodBase method = MethodBase.GetCurrentMethod(); /// handler.Invoke( this, method, new object[] { parameter } ); /// } /// </code> /// </remarks> /// <param name="typeBuilder"><see cref="TypeBuilder"/> being constructed.</param> /// <param name="parameters"></param> /// <param name="handlerField"></param> private static void WriteILForMethod( MethodBuilder builder, System.Type[] parameters, FieldBuilder handlerField ) { int arrayPositionInStack = 1; ILGenerator ilGenerator = builder.GetILGenerator(); ilGenerator.DeclareLocal( typeof( MethodBase ) ); if (builder.ReturnType != typeof(void)) { ilGenerator.DeclareLocal(builder.ReturnType); arrayPositionInStack = 2; } ilGenerator.DeclareLocal( typeof(object[]) ); ilGenerator.Emit(OpCodes.Call, typeof(MethodBase).GetMethod("GetCurrentMethod") ); ilGenerator.Emit(OpCodes.Stloc_0); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldfld, handlerField ); ilGenerator.Emit(OpCodes.Ldarg_0); ilGenerator.Emit(OpCodes.Ldloc_0); ilGenerator.Emit(OpCodes.Ldc_I4, parameters.Length); ilGenerator.Emit(OpCodes.Newarr, typeof(object) ); if (parameters.Length != 0) { ilGenerator.Emit(OpCodes.Stloc, arrayPositionInStack); ilGenerator.Emit(OpCodes.Ldloc, arrayPositionInStack); } for (int c=0; c<parameters.Length; c++) { ilGenerator.Emit(OpCodes.Ldc_I4, c); ilGenerator.Emit(OpCodes.Ldarg, c+1); if (parameters[c].IsValueType) { ilGenerator.Emit(OpCodes.Box, parameters[c].UnderlyingSystemType); } ilGenerator.Emit(OpCodes.Stelem_Ref); ilGenerator.Emit(OpCodes.Ldloc, arrayPositionInStack); } ilGenerator.Emit(OpCodes.Callvirt, typeof(IInvocationHandler).GetMethod("Invoke") ); if (builder.ReturnType != typeof(void)) { if (!builder.ReturnType.IsValueType) { ilGenerator.Emit(OpCodes.Castclass, builder.ReturnType); } else { ilGenerator.Emit(OpCodes.Unbox, builder.ReturnType); ilGenerator.Emit(ConvertTypeToOpCode(builder.ReturnType)); } ilGenerator.Emit(OpCodes.Stloc, 1); Label label = ilGenerator.DefineLabel(); ilGenerator.Emit(OpCodes.Br_S, label); ilGenerator.MarkLabel(label); ilGenerator.Emit(OpCodes.Ldloc, 1); } else { ilGenerator.Emit(OpCodes.Pop); } ilGenerator.Emit(OpCodes.Ret); } /// <summary> /// Converts a Value type to a correspondent OpCode of /// </summary> /// <param name="type"></param> /// <returns></returns> private static OpCode ConvertTypeToOpCode( Type type ) { if ( type.Equals( typeof(Int32) ) ) { return OpCodes.Ldind_I4; } else if ( type.Equals( typeof(Int16) ) ) { return OpCodes.Ldind_I2; } else if ( type.Equals( typeof(Int64) ) ) { return OpCodes.Ldind_I8; } else if ( type.Equals( typeof(Single) ) ) { return OpCodes.Ldind_R4; } else if ( type.Equals( typeof(Double) ) ) { return OpCodes.Ldind_R8; } else if ( type.Equals( typeof(UInt16) ) ) { return OpCodes.Ldind_U2; } else if ( type.Equals( typeof(UInt32) ) ) { return OpCodes.Ldind_U4; } else { throw new ArgumentException("Type " + type + " could not be converted to a OpCode"); } } } } 1.1 avalon-sandbox/avalon-net/DynamicProxy/DynamicProxyTest/Apache.Avalon.DynamicProxy.Test.csproj Index: Apache.Avalon.DynamicProxy.Test.csproj =================================================================== <VisualStudioProject> <CSHARP ProjectType = "Local" ProductVersion = "7.10.3077" SchemaVersion = "2.0" ProjectGuid = "{EF89321E-FB2A-41B6-85B3-794D50A55CF1}" > <Build> <Settings ApplicationIcon = "" AssemblyKeyContainerName = "" AssemblyName = "Apache.Avalon.DynamicProxy.Test" AssemblyOriginatorKeyFile = "" DefaultClientScript = "JScript" DefaultHTMLPageLayout = "Grid" DefaultTargetSchema = "IE50" DelaySign = "false" OutputType = "Library" PreBuildEvent = "" PostBuildEvent = "" RootNamespace = "Apache.Avalon.DynamicProxy.Test" RunPostBuildEvent = "OnBuildSuccess" StartupObject = "" > <Config Name = "Debug" AllowUnsafeBlocks = "false" BaseAddress = "285212672" CheckForOverflowUnderflow = "false" ConfigurationOverrideFile = "" DefineConstants = "DEBUG;TRACE" DocumentationFile = "" DebugSymbols = "true" FileAlignment = "4096" IncrementalBuild = "false" NoStdLib = "false" NoWarn = "" Optimize = "false" OutputPath = "bin\Debug\" RegisterForComInterop = "false" RemoveIntegerChecks = "false" TreatWarningsAsErrors = "false" WarningLevel = "4" /> <Config Name = "Release" AllowUnsafeBlocks = "false" BaseAddress = "285212672" CheckForOverflowUnderflow = "false" ConfigurationOverrideFile = "" DefineConstants = "TRACE" DocumentationFile = "" DebugSymbols = "false" FileAlignment = "4096" IncrementalBuild = "false" NoStdLib = "false" NoWarn = "" Optimize = "true" OutputPath = "bin\Release\" RegisterForComInterop = "false" RemoveIntegerChecks = "false" TreatWarningsAsErrors = "false" WarningLevel = "4" /> </Settings> <References> <Reference Name = "System" AssemblyName = "System" HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.dll" /> <Reference Name = "System.Data" AssemblyName = "System.Data" HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.Data.dll" /> <Reference Name = "System.XML" AssemblyName = "System.Xml" HintPath = "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\System.XML.dll" /> <Reference Name = "DProxy" Project = "{70EE6AF2-1F6D-4CC5-A1B2-C3182F035F67}" Package = "{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}" /> <Reference Name = "nunit.framework" AssemblyName = "nunit.framework" HintPath = "..\..\..\..\..\..\dotnet\NUnit2\bin\nunit.framework.dll" /> </References> </Build> <Files> <Include> <File RelPath = "AssemblyInfo.cs" SubType = "Code" BuildAction = "Compile" /> <File RelPath = "ProxyGeneratorTestCase.cs" SubType = "Code" BuildAction = "Compile" /> </Include> </Files> </CSHARP> </VisualStudioProject> 1.1 avalon-sandbox/avalon-net/DynamicProxy/DynamicProxyTest/AssemblyInfo.cs Index: AssemblyInfo.cs =================================================================== // 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. using System.Reflection; using System.Runtime.CompilerServices; [assembly: AssemblyTitle("Avalon DynamicProxy Test cases")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("The Apache Software Foundation")] [assembly: AssemblyProduct("Avalon DynamicProxy Test cases")] [assembly: AssemblyCopyright("Copyright (c) 2004 The Apache Software Foundation")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] [assembly: AssemblyVersion("1.0.0.0")] 1.1 avalon-sandbox/avalon-net/DynamicProxy/DynamicProxyTest/ProxyGeneratorTestCase.cs Index: ProxyGeneratorTestCase.cs =================================================================== // 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.DynamicProxy.Test { using System; using System.Reflection; using NUnit.Framework; using Apache.Avalon.DynamicProxy; /// <summary> /// Summary description for ProxyGeneratorTestCase. /// </summary> [TestFixture] public class ProxyGeneratorTestCase : Assertion, IInvocationHandler, IMyInterface { protected String nameProperty; [Test] public void TestSimpleCase() { object proxy = ProxyGenerator.CreateProxy( new Type[] { typeof(IMyInterface) }, this ); AssertNotNull( proxy ); Assert( typeof(IMyInterface).IsAssignableFrom( proxy.GetType() ) ); IMyInterface inter = (IMyInterface) proxy; inter.Calc(1, "ola"); inter.Nome = "opa"; AssertEquals( "opa", inter.Nome ); AssertEquals( 45, inter.Calc( 20, 25 ) ); } #region IInvocationHandler Members public object Invoke(object obj, MethodBase method, params object[] arguments) { Type[] parameters = new Type[arguments.Length]; for(int i=0; i < arguments.Length; i++ ) { parameters[i] = arguments[i].GetType(); } MethodInfo ourMethod = this.GetType().GetMethod( method.Name, parameters ); AssertNotNull( ourMethod ); return ourMethod.Invoke( this, arguments ); } #endregion #region IMyInterface Members public String Nome { get { return nameProperty; } set { nameProperty = value; } } public void Calc(int x, String y) { } public void Calc(int x, String y, Single ip) { } public int Calc(int x, int y) { return x + y; } public int Calc(int x, int y, int z, Single h) { return x + y + z + (int)h; } #endregion } /// <summary> /// /// </summary> public interface IMyInterface { String Nome { get; set; } void Calc(int x, String y); void Calc(int x, String y, Single ip); int Calc(int x, int y); int Calc(int x, int y, int z, Single h); } public class MyTest : IMyInterface { IInvocationHandler handler = null; #region IMyInterface Members public String Nome { get { // TODO: Add MyTest.Nome getter implementation return null; } set { // TODO: Add MyTest.Nome setter implementation } } public void Calc(int x, String y) { MethodBase method = MethodBase.GetCurrentMethod(); handler.Invoke( this, method, x, y ); } public void Calc(int x, String y, Single ip) { MethodBase method = MethodBase.GetCurrentMethod(); handler.Invoke( this, method, x, y, ip ); } public int Calc(int x, int y) { MethodBase method = MethodBase.GetCurrentMethod(); return (int) handler.Invoke( this, method, x, y ); } public int Calc(int x, int y, int z, Single h) { MethodBase method = MethodBase.GetCurrentMethod(); return (int) handler.Invoke( this, method, x, y, h ); } #endregion } }
--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]