Author: hammett
Date: Mon Sep  6 13:43:16 2004
New Revision: 43424

Added:
   avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/CodeGenerators/
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/CodeGenerators/BaseCodeGenerator.cs
   (contents, props changed)
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/CodeGenerators/ClassProxyGenerator.cs
   (contents, props changed)
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/CodeGenerators/InterfaceProxyGenerator.cs
   (contents, props changed)
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/CodeGenerators/OpCodesDictionary.cs
   (contents, props changed)
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/IProxyBuilder.cs
   (contents, props changed)
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/ProxyBuilderImpl.cs
   (contents, props changed)
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/IMyInterface.cs
   (contents, props changed)
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/IMySecondInterface.cs
   (contents, props changed)
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/IServiceStatus.cs
   (contents, props changed)
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/MyInterfaceImpl.cs
   (contents, props changed)
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/MySecondInterfaceImpl.cs
   (contents, props changed)
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/ServiceStatusImpl.cs
   (contents, props changed)
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Classes/
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Classes/NoVirtualMethodClass.cs
   (contents, props changed)
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Classes/SealedMethodsClass.cs
   (contents, props changed)
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Classes/ServiceClass.cs
   (contents, props changed)
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Classes/SpecializedServiceClass.cs
   (contents, props changed)
Removed:
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/IMyInterface.cs
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/IMySecondInterface.cs
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/IServiceStatus.cs
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/MyInterfaceImpl.cs
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/MySecondInterfaceImpl.cs
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ServiceStatusImpl.cs
Modified:
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Apache.Avalon.DynamicProxy.csproj
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Apache.Avalon.DynamicProxy.Test.csproj
   
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ProxyGeneratorTestCase.cs
   avalon/trunk/central/laboratory/avalon-net/DynamicProxy/ProxyGenerator.cs
Log:
Supports proxying classes and interfaces now.

Modified: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Apache.Avalon.DynamicProxy.csproj
==============================================================================
--- 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Apache.Avalon.DynamicProxy.csproj
   (original)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Apache.Avalon.DynamicProxy.csproj
   Mon Sep  6 13:43:16 2004
@@ -103,6 +103,36 @@
                     SubType = "Code"
                     BuildAction = "Compile"
                 />
+                <File
+                    RelPath = "Builder\IProxyBuilder.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Builder\ProxyBuilderImpl.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Builder\CodeGenerators\BaseCodeGenerator.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Builder\CodeGenerators\ClassProxyGenerator.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = 
"Builder\CodeGenerators\InterfaceProxyGenerator.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "Builder\CodeGenerators\OpCodesDictionary.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
             </Include>
         </Files>
     </CSHARP>

Added: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/CodeGenerators/BaseCodeGenerator.cs
==============================================================================
--- (empty file)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/CodeGenerators/BaseCodeGenerator.cs
 Mon Sep  6 13:43:16 2004
@@ -0,0 +1,372 @@
+ // 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.Builder.CodeGenerators
+{
+       using System;
+       using System.Collections;
+       using System.Reflection;
+       using System.Reflection.Emit;
+
+       /// <summary>
+       /// Summary description for BaseCodeGenerator.
+       /// </summary>
+       public abstract class BaseCodeGenerator
+       {
+               private TypeBuilder m_typeBuilder;
+               private FieldBuilder m_handlerField;
+               private IList m_generated = new ArrayList();
+
+               protected TypeBuilder MainTypeBuilder
+               {
+                       get { return m_typeBuilder; }
+               }
+
+               protected FieldBuilder HandlerFieldBuilder
+               {
+                       get { return m_handlerField; }
+               }
+
+               protected virtual ModuleBuilder CreateDynamicModule()
+               {
+                       AssemblyName assemblyName = new AssemblyName();
+                       assemblyName.Name = "DynamicAssemblyProxyGen";
+
+                       AssemblyBuilder assemblyBuilder =
+                               AppDomain.CurrentDomain.DefineDynamicAssembly(
+                                       assemblyName,
+                                       AssemblyBuilderAccess.Run);
+
+                       return 
assemblyBuilder.DefineDynamicModule(assemblyName.Name, true);
+               }
+
+               protected virtual TypeBuilder CreateTypeBuilder(Type baseType, 
Type[] interfaces)
+               {
+                       ModuleBuilder moduleBuilder = CreateDynamicModule();
+
+                       m_typeBuilder = moduleBuilder.DefineType(
+                               "ProxyType", TypeAttributes.Public | 
TypeAttributes.Class, baseType, interfaces);
+
+                       m_handlerField = GenerateField();
+                       ConstructorBuilder constr = GenerateConstructor();
+
+                       return m_typeBuilder;
+               }
+
+               /// <summary>
+               /// Generates a public field holding the <see 
cref="IInvocationHandler"/>
+               /// </summary>
+               /// <returns><see cref="FieldBuilder"/> instance</returns>
+               protected FieldBuilder GenerateField()
+               {
+                       return m_typeBuilder.DefineField("handler",
+                                                        typeof 
(IInvocationHandler), FieldAttributes.Public);
+               }
+
+               /// <summary>
+               /// Generates one public constructor receiving 
+               /// the <see cref="IInvocationHandler"/> instance.
+               /// </summary>
+               /// <returns><see cref="ConstructorBuilder"/> instance</returns>
+               protected ConstructorBuilder GenerateConstructor()
+               {
+                       ConstructorBuilder consBuilder = 
m_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, m_handlerField);
+                       ilGenerator.Emit(OpCodes.Ret);
+
+                       return consBuilder;
+               }
+
+               /// <summary>
+               /// 
+               /// </summary>
+               /// <param name="interfaces"></param>
+               protected void GenerateInterfaceImplementation(Type[] 
interfaces)
+               {
+                       foreach(Type inter in interfaces)
+                       {
+                               GenerateTypeImplementation(inter);
+                       }
+               }
+
+               /// <summary>
+               /// Iterates over the interfaces and generate implementation 
+               /// for each method in it.
+               /// </summary>
+               /// <param name="type">Interface type</param>
+               protected void GenerateTypeImplementation(Type type)
+               {
+                       if (m_generated.Contains(type))
+                       {
+                               return;
+                       }
+                       else
+                       {
+                               m_generated.Add( type );
+                       }
+
+                       Type[] baseInterfaces = type.FindInterfaces(new 
TypeFilter(NoFilterImpl), type);
+
+                       GenerateInterfaceImplementation(baseInterfaces);
+                       PropertyBuilder[] propertiesBuilder = 
GenerateProperties(type);
+                       GenerateMethods(type, propertiesBuilder);
+               }
+
+               protected virtual PropertyBuilder[] GenerateProperties( Type 
inter )
+               {
+                       PropertyInfo[] properties = inter.GetProperties();
+                       PropertyBuilder[] propertiesBuilder = new 
PropertyBuilder[properties.Length];
+
+                       for(int i = 0; i < properties.Length; i++)
+                       {
+                               propertiesBuilder[i] = 
GeneratePropertyImplementation(properties[i]);
+                       }
+
+                       return propertiesBuilder;
+               }
+
+               protected virtual void GenerateMethods( Type inter, 
PropertyBuilder[] propertiesBuilder )
+               {
+                       MethodInfo[] methods = inter.GetMethods();
+
+                       foreach(MethodInfo method in methods)
+                       {
+                               GenerateMethodImplementation(method, 
propertiesBuilder);
+                       }
+               }
+
+               /// <summary>
+               /// Generate property implementation
+               /// </summary>
+               /// <param name="property"></param>
+               protected PropertyBuilder 
GeneratePropertyImplementation(PropertyInfo property)
+               {
+                       return m_typeBuilder.DefineProperty(
+                               property.Name, property.Attributes, 
property.PropertyType, null);
+               }
+
+               /// <summary>
+               /// Generates implementation for each method.
+               /// </summary>
+               /// <param name="method"></param>
+               /// <param name="properties"></param>
+               protected void GenerateMethodImplementation(
+                       MethodInfo method, PropertyBuilder[] properties)
+               {
+                       if (method.IsFinal)
+                       {
+                               return;
+                       }
+
+                       ParameterInfo[] parameterInfo = method.GetParameters();
+
+                       Type[] parameters = new 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 =
+                               m_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(method, methodBuilder, parameters, 
HandlerFieldBuilder);
+               }
+
+               /// <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="builder"><see cref="MethodBuilder"/> being 
constructed.</param>
+               /// <param name="parameters"></param>
+               /// <param name="handlerField"></param>
+               protected void WriteILForMethod(MethodInfo method, 
MethodBuilder builder,
+                                               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.Ldtoken, method);
+                       ilGenerator.Emit(OpCodes.Call, typeof 
(MethodBase).GetMethod("GetMethodFromHandle"));
+
+                       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>
+               protected virtual OpCode ConvertTypeToOpCode(Type type)
+               {
+                       if (type.IsEnum)
+                       {
+                               Enum baseType = (Enum) 
Activator.CreateInstance(type);
+                               TypeCode code = baseType.GetTypeCode();
+
+                               switch(code)
+                               {
+                                       case TypeCode.Byte:
+                                               type = typeof (Byte);
+                                               break;
+                                       case TypeCode.Int16:
+                                               type = typeof (Int16);
+                                               break;
+                                       case TypeCode.Int32:
+                                               type = typeof (Int32);
+                                               break;
+                                       case TypeCode.Int64:
+                                               type = typeof (Int64);
+                                               break;
+                               }
+
+                               return ConvertTypeToOpCode(type);
+                       }
+
+                       OpCode opCode = OpCodesDictionary.Instance[ type ];
+
+                       if (Object.ReferenceEquals(opCode, 
OpCodesDictionary.EmptyOpCode))
+                       {
+                               throw new ArgumentException("Type " + type + " 
could not be converted to a OpCode");
+                       }
+
+                       return opCode;
+               }
+
+               public static bool NoFilterImpl(Type type, object criteria)
+               {
+                       return true;
+               }
+       }
+}
\ No newline at end of file

Added: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/CodeGenerators/ClassProxyGenerator.cs
==============================================================================
--- (empty file)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/CodeGenerators/ClassProxyGenerator.cs
       Mon Sep  6 13:43:16 2004
@@ -0,0 +1,34 @@
+// 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.Builder.CodeGenerators
+{
+       using System;
+
+       /// <summary>
+       /// Summary description for ClassProxyGenerator.
+       /// </summary>
+       public class ClassProxyGenerator : BaseCodeGenerator
+       {
+               public Type GenerateCode(Type baseClass)
+               {
+                       // TODO: interfaces of base class
+                       
+                       CreateTypeBuilder( baseClass, new Type[0] );
+                       GenerateTypeImplementation( baseClass );
+
+                       return MainTypeBuilder.CreateType();
+               }
+       }
+}

Added: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/CodeGenerators/InterfaceProxyGenerator.cs
==============================================================================
--- (empty file)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/CodeGenerators/InterfaceProxyGenerator.cs
   Mon Sep  6 13:43:16 2004
@@ -0,0 +1,37 @@
+ // 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.Builder.CodeGenerators
+{
+       using System;
+       using System.Reflection;
+       using System.Reflection.Emit;
+
+       /// <summary>
+       /// Summary description for InterfaceProxyGenerator.
+       /// </summary>
+       public class InterfaceProxyGenerator : BaseCodeGenerator
+       {
+               public InterfaceProxyGenerator()
+               {
+               }
+
+               public Type GenerateCode(Type[] interfaces)
+               {
+                       CreateTypeBuilder( null, interfaces );
+                       GenerateInterfaceImplementation( interfaces );
+                       return MainTypeBuilder.CreateType();
+               }
+       }
+}
\ No newline at end of file

Added: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/CodeGenerators/OpCodesDictionary.cs
==============================================================================
--- (empty file)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/CodeGenerators/OpCodesDictionary.cs
 Mon Sep  6 13:43:16 2004
@@ -0,0 +1,64 @@
+using System.Reflection.Emit;
+// 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.Builder.CodeGenerators
+{
+       using System;
+       using System.Collections;
+
+       /// <summary>
+       /// Summary description for OpCodesDictionary.
+       /// </summary>
+       public sealed class OpCodesDictionary : DictionaryBase
+       {
+               private static readonly OpCodesDictionary m_dict = new 
OpCodesDictionary();
+
+               private static readonly OpCode m_emptyOpCode = new OpCode();
+
+               private OpCodesDictionary() : base()
+               {
+                       Dictionary[ typeof (Int16) ] = OpCodes.Ldind_I2;
+                       Dictionary[ typeof (Int32) ] = OpCodes.Ldind_I4;
+                       Dictionary[ typeof (Int64) ] = OpCodes.Ldind_I8;
+                       Dictionary[ typeof (float) ] = OpCodes.Ldind_R4;
+                       Dictionary[ typeof (double) ] = OpCodes.Ldind_R8;
+                       Dictionary[ typeof (UInt16) ] = OpCodes.Ldind_U2;
+                       Dictionary[ typeof (UInt32) ] = OpCodes.Ldind_U4;
+                       Dictionary[ typeof (bool) ] = OpCodes.Ldind_I4;
+               }
+
+               public OpCode this[Type type]
+               {
+                       get
+                       {
+                               if (Dictionary.Contains(type))
+                               {
+                                       return (OpCode) Dictionary[ type ];
+                               }
+                               return EmptyOpCode;
+                       }
+               }
+
+               public static OpCodesDictionary Instance
+               {
+                       get { return m_dict; }
+               }
+
+               public static OpCode EmptyOpCode
+               {
+                       get { return m_emptyOpCode; }
+               }
+       }
+}
\ No newline at end of file

Added: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/IProxyBuilder.cs
==============================================================================
--- (empty file)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/IProxyBuilder.cs
    Mon Sep  6 13:43:16 2004
@@ -0,0 +1,28 @@
+// 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.Builder
+{
+       using System;
+
+       /// <summary>
+       /// Summary description for IProxyBuilder.
+       /// </summary>
+       public interface IProxyBuilder
+       {
+               Type CreateInterfaceProxy( Type[] interfaces );
+
+               Type CreateClassProxy( Type theClass );
+       }
+}

Added: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/ProxyBuilderImpl.cs
==============================================================================
--- (empty file)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/Builder/ProxyBuilderImpl.cs
 Mon Sep  6 13:43:16 2004
@@ -0,0 +1,41 @@
+using Apache.Avalon.DynamicProxy.Builder.CodeGenerators;
+// 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.Builder
+{
+       using System;
+
+       /// <summary>
+       /// Summary description for ProxyBuilderImpl.
+       /// </summary>
+       public class ProxyBuilderImpl : IProxyBuilder
+       {
+               #region IProxyBuilder Members
+
+               public Type CreateInterfaceProxy(Type[] interfaces)
+               {
+                       InterfaceProxyGenerator generator = new 
InterfaceProxyGenerator();
+                       return generator.GenerateCode( interfaces );
+               }
+
+               public Type CreateClassProxy(Type theClass)
+               {
+                       ClassProxyGenerator generator = new 
ClassProxyGenerator();
+                       return generator.GenerateCode( theClass );
+               }
+
+               #endregion
+       }
+}

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
     Mon Sep  6 13:43:16 2004
@@ -99,37 +99,57 @@
                     BuildAction = "Compile"
                 />
                 <File
-                    RelPath = "IMyInterface.cs"
+                    RelPath = "ProxyGeneratorTestCase.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
                 />
                 <File
-                    RelPath = "IMySecondInterface.cs"
+                    RelPath = "Classes\NoVirtualMethodClass.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
                 />
                 <File
-                    RelPath = "IServiceStatus.cs"
+                    RelPath = "Classes\SealedMethodsClass.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
                 />
                 <File
-                    RelPath = "MyInterfaceImpl.cs"
+                    RelPath = "Classes\ServiceClass.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
                 />
                 <File
-                    RelPath = "MySecondInterfaceImpl.cs"
+                    RelPath = "Classes\SpecializedServiceClass.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
                 />
                 <File
-                    RelPath = "ProxyGeneratorTestCase.cs"
+                    RelPath = "ClassInterfaces\IMyInterface.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "ClassInterfaces\IMySecondInterface.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "ClassInterfaces\IServiceStatus.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "ClassInterfaces\MyInterfaceImpl.cs"
+                    SubType = "Code"
+                    BuildAction = "Compile"
+                />
+                <File
+                    RelPath = "ClassInterfaces\MySecondInterfaceImpl.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
                 />
                 <File
-                    RelPath = "ServiceStatusImpl.cs"
+                    RelPath = "ClassInterfaces\ServiceStatusImpl.cs"
                     SubType = "Code"
                     BuildAction = "Compile"
                 />

Added: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/IMyInterface.cs
==============================================================================
--- (empty file)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/IMyInterface.cs
    Mon Sep  6 13:43:16 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.DynamicProxy.Test.ClassInterfaces
+{
+       using System;
+
+       /// <summary>
+       /// Summary description for IMyInterface.
+       /// </summary>
+       public interface IMyInterface
+       {
+               String Name
+               {
+                       get;
+                       set;
+               }
+
+               bool Started
+               {
+                       get;
+                       set;
+               }
+
+               int Calc(int x, int y);
+
+               int Calc(int x, int y, int z, Single k);
+       }
+}

Added: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/IMySecondInterface.cs
==============================================================================
--- (empty file)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/IMySecondInterface.cs
      Mon Sep  6 13:43:16 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.DynamicProxy.Test.ClassInterfaces
+{
+       using System;
+
+       /// <summary>
+       /// Summary description for IMySecondInterface.
+       /// </summary>
+       public interface IMySecondInterface : IMyInterface
+       {
+               String Address
+               {
+                       get;
+                       set;
+               }
+       }
+}

Added: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/IServiceStatus.cs
==============================================================================
--- (empty file)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/IServiceStatus.cs
  Mon Sep  6 13:43:16 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.DynamicProxy.Test.ClassInterfaces
+{
+       using System;
+
+       /// <summary>
+       /// Simple enum declaration
+       /// </summary>
+       public enum State
+       {
+               Valid, 
+               Invalid
+       }
+
+       /// <summary>
+       /// Summary description for IServiceStatus.
+       /// </summary>
+       public interface IServiceStatus
+       {
+               int Requests
+               {
+                       get;
+               }
+
+               State ActualState
+               {
+                       get;
+               }
+
+               void ChangeState(State state);
+       }
+}

Added: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/MyInterfaceImpl.cs
==============================================================================
--- (empty file)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/MyInterfaceImpl.cs
 Mon Sep  6 13:43:16 2004
@@ -0,0 +1,69 @@
+// 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.ClassInterfaces
+{
+       using System;
+
+       /// <summary>
+       /// Summary description for MyInterfaceImpl.
+       /// </summary>
+       public class MyInterfaceImpl : IMyInterface
+       {
+               private String m_name;
+               private bool m_started;
+
+               public MyInterfaceImpl()
+               {
+               }
+
+               #region IMyInterface Members
+
+               public String Name
+               {
+                       get
+                       {
+                               return m_name;
+                       }
+                       set
+                       {
+                               m_name = value;
+                       }
+               }
+
+               public bool Started
+               {
+                       get
+                       {
+                               return m_started;
+                       }
+                       set
+                       {
+                               m_started = value;
+                       }
+               }
+
+               public int Calc(int x, int y)
+               {
+                       return x + y;
+               }
+
+               public int Calc(int x, int y, int z, Single k)
+               {
+                       return x + y + z + (int)k;
+               }
+
+               #endregion
+       }
+}

Added: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/MySecondInterfaceImpl.cs
==============================================================================
--- (empty file)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/MySecondInterfaceImpl.cs
   Mon Sep  6 13:43:16 2004
@@ -0,0 +1,46 @@
+// 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.ClassInterfaces
+{
+       using System;
+
+       /// <summary>
+       /// Summary description for MySecondInterfaceImpl.
+       /// </summary>
+       public class MySecondInterfaceImpl : MyInterfaceImpl, IMySecondInterface
+       {
+               private String m_address;
+
+               public MySecondInterfaceImpl()
+               {
+               }
+
+               #region IMySecondInterface Members
+
+               public String Address
+               {
+                       get
+                       {
+                               return m_address;
+                       }
+                       set
+                       {
+                               m_address = value;
+                       }
+               }
+
+               #endregion
+       }
+}

Added: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/ServiceStatusImpl.cs
==============================================================================
--- (empty file)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ClassInterfaces/ServiceStatusImpl.cs
       Mon Sep  6 13:43:16 2004
@@ -0,0 +1,55 @@
+// 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.ClassInterfaces
+{
+       using System;
+
+       /// <summary>
+       /// Summary description for ServiceStatusImpl.
+       /// </summary>
+       public class ServiceStatusImpl : IServiceStatus
+       {
+               private State m_state = State.Invalid;
+
+               public ServiceStatusImpl()
+               {
+               }
+
+               #region IServiceStatus Members
+
+               public int Requests
+               {
+                       get
+                       {
+                               return 10;
+                       }
+               }
+
+               public State ActualState
+               {
+                       get
+                       {
+                               return m_state;
+                       }
+               }
+
+               public void ChangeState(State state)
+               {
+                       m_state = state;
+               }
+
+               #endregion
+       }
+}

Added: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Classes/NoVirtualMethodClass.cs
==============================================================================
--- (empty file)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Classes/NoVirtualMethodClass.cs
    Mon Sep  6 13:43:16 2004
@@ -0,0 +1,29 @@
+// 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.Classes
+{
+       using System;
+
+       /// <summary>
+       /// Summary description for NoVirtualMethodClass.
+       /// </summary>
+       public class NoVirtualMethodClass
+       {
+               public int Sum(int b1, int b2)
+               {
+                       return b1 + b2;
+               }
+       }
+}

Added: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Classes/SealedMethodsClass.cs
==============================================================================
--- (empty file)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Classes/SealedMethodsClass.cs
      Mon Sep  6 13:43:16 2004
@@ -0,0 +1,29 @@
+// 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.Classes
+{
+       using System;
+
+       /// <summary>
+       /// Summary description for SealedMethodsClass.
+       /// </summary>
+       public class SealedMethodsClass : ServiceClass
+       {
+               public override sealed int Sum(int b1, int b2)
+               {
+                       return b1 + b2;
+               }
+       }
+}

Added: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Classes/ServiceClass.cs
==============================================================================
--- (empty file)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Classes/ServiceClass.cs
    Mon Sep  6 13:43:16 2004
@@ -0,0 +1,74 @@
+ // 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.Classes
+{
+       using System;
+
+       /// <summary>
+       /// Summary description for ServiceClass.
+       /// </summary>
+       public class ServiceClass
+       {
+               public virtual int Sum(int b1, int b2)
+               {
+                       return b1 + b2;
+               }
+
+               public virtual byte Sum(byte b1, byte b2)
+               {
+                       return System.Convert.ToByte( b1 + b2 );
+               }
+
+               public virtual long Sum(long b1, long b2)
+               {
+                       return b1 + b2;
+               }
+
+               public virtual short Sum(short b1, short b2)
+               {
+                       return (short) (b1 + b2);
+               }
+
+               public virtual float Sum(float b1, float b2)
+               {
+                       return b1 + b2;
+               }
+
+               public virtual double Sum(double b1, double b2)
+               {
+                       return b1 + b2;
+               }
+
+               public virtual UInt16 Sum(UInt16 b1, UInt16 b2)
+               {
+                       return (UInt16) (b1 + b2);
+               }
+
+               public virtual UInt32 Sum(UInt32 b1, UInt32 b2)
+               {
+                       return b1 + b2;
+               }
+
+               public virtual UInt64 Sum(UInt64 b1, UInt64 b2)
+               {
+                       return b1 + b2;
+               }
+
+               public virtual bool Valid
+               {
+                       get { return true; }
+               }
+       }
+}
\ No newline at end of file

Added: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Classes/SpecializedServiceClass.cs
==============================================================================
--- (empty file)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/Classes/SpecializedServiceClass.cs
 Mon Sep  6 13:43:16 2004
@@ -0,0 +1,29 @@
+// 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.Classes
+{
+       using System;
+
+       /// <summary>
+       /// Summary description for SpecializedServiceClass.
+       /// </summary>
+       public class SpecializedServiceClass : ServiceClass
+       {
+               public virtual int Subtract(int b1, int b2)
+               {
+                       return b1 - b2;
+               }
+       }
+}

Modified: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ProxyGeneratorTestCase.cs
==============================================================================
--- 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ProxyGeneratorTestCase.cs
  (original)
+++ 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/DynamicProxyTest/ProxyGeneratorTestCase.cs
  Mon Sep  6 13:43:16 2004
@@ -20,6 +20,8 @@
        using NUnit.Framework;
 
        using Apache.Avalon.DynamicProxy;
+       using Apache.Avalon.DynamicProxy.Test.Classes;
+       using Apache.Avalon.DynamicProxy.Test.ClassInterfaces;
 
        /// <summary>
        /// Summary description for ProxyGeneratorTestCase.
@@ -28,6 +30,100 @@
        public class ProxyGeneratorTestCase : Assertion
        {
                [Test]
+               public void ProxyForClass()
+               {
+                       object proxy = ProxyGenerator.CreateClassProxy( 
+                               typeof(ServiceClass), new 
ResultModifiedInvocationHandler( new ServiceClass() ) );
+                       
+                       AssertNotNull( proxy );
+                       Assert( typeof(ServiceClass).IsAssignableFrom( 
proxy.GetType() ) );
+
+                       ServiceClass inter = (ServiceClass) proxy;
+
+                       AssertEquals( 44, inter.Sum( 20, 25 ) );
+                       AssertEquals( true, inter.Valid );
+               }
+
+               [Test]
+               public void ProxyForClassWithSuperClass()
+               {
+                       object proxy = ProxyGenerator.CreateClassProxy( 
+                               typeof(SpecializedServiceClass), new 
ResultModifiedInvocationHandler( new SpecializedServiceClass() ) );
+                       
+                       AssertNotNull( proxy );
+                       Assert( typeof(ServiceClass).IsAssignableFrom( 
proxy.GetType() ) );
+                       Assert( 
typeof(SpecializedServiceClass).IsAssignableFrom( proxy.GetType() ) );
+
+                       SpecializedServiceClass inter = 
(SpecializedServiceClass) proxy;
+
+                       AssertEquals( 44, inter.Sum( 20, 25 ) );
+                       AssertEquals( -6, inter.Subtract( 20, 25 ) );
+                       AssertEquals( true, inter.Valid );
+               }
+
+               [Test]
+               public void ProxyingClassWithoutVirtualMethods()
+               {
+                       object proxy = ProxyGenerator.CreateClassProxy( 
+                               typeof(NoVirtualMethodClass), new 
ResultModifiedInvocationHandler( new SpecializedServiceClass() ) );
+                       
+                       AssertNotNull( proxy );
+                       Assert( typeof(NoVirtualMethodClass).IsAssignableFrom( 
proxy.GetType() ) );
+
+                       NoVirtualMethodClass inter = (NoVirtualMethodClass) 
proxy;
+
+                       AssertEquals( 45, inter.Sum( 20, 25 ) );
+               }
+
+               [Test]
+               public void ProxyingClassWithSealedMethods()
+               {
+                       object proxy = ProxyGenerator.CreateClassProxy( 
+                               typeof(SealedMethodsClass), new 
ResultModifiedInvocationHandler( new SpecializedServiceClass() ) );
+                       
+                       AssertNotNull( proxy );
+                       Assert( typeof(SealedMethodsClass).IsAssignableFrom( 
proxy.GetType() ) );
+
+                       SealedMethodsClass inter = (SealedMethodsClass) proxy;
+
+                       AssertEquals( 45, inter.Sum( 20, 25 ) );
+               }
+
+               [Test]
+               public void CreateClassProxyInvalidArguments()
+               {
+                       try
+                       {
+                               ProxyGenerator.CreateClassProxy( 
+                                       typeof(ICloneable), new 
StandardInvocationHandler( new SpecializedServiceClass() ) );
+                       }
+                       catch(ArgumentException)
+                       {
+                               // Expected
+                       }
+
+                       try
+                       {
+                               ProxyGenerator.CreateClassProxy( 
+                                       null, new StandardInvocationHandler( 
new SpecializedServiceClass() ) );
+                       }
+                       catch(ArgumentNullException)
+                       {
+                               // Expected
+                       }
+
+                       try
+                       {
+                               ProxyGenerator.CreateClassProxy( 
+                                       typeof(SpecializedServiceClass), null );
+                       }
+                       catch(ArgumentNullException)
+                       {
+                               // Expected
+                       }
+               }
+
+               [Test]
                public void TestGenerationSimpleInterface()
                {
                        object proxy = ProxyGenerator.CreateProxy( 
@@ -98,6 +194,22 @@
 
                        #endregion
                }
+       }
+
+       public class ResultModifiedInvocationHandler : StandardInvocationHandler
+       {
+               public ResultModifiedInvocationHandler( object instanceDelegate 
) : base(instanceDelegate)
+               {
+               }
+
+               protected override void PostInvoke(object proxy, 
System.Reflection.MethodInfo method, ref object returnValue, params object[] 
arguments)
+               {
+                       if ( returnValue != null && returnValue.GetType() == 
typeof(int))
+                       {
+                               int value = (int) returnValue;
+                               returnValue = --value;
+                       }
+               }
        }
 }
 

Modified: 
avalon/trunk/central/laboratory/avalon-net/DynamicProxy/ProxyGenerator.cs
==============================================================================
--- avalon/trunk/central/laboratory/avalon-net/DynamicProxy/ProxyGenerator.cs   
(original)
+++ avalon/trunk/central/laboratory/avalon-net/DynamicProxy/ProxyGenerator.cs   
Mon Sep  6 13:43:16 2004
@@ -1,437 +1,116 @@
-// 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>
-       /// <remarks>
-       /// This proxy implementation currently doesn't not supports ref and 
out arguments 
-       /// in methods.
-       /// </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="theInterface">Interface to be 
implemented</param>
-               /// <param name="handler">instance of <see 
cref="IInvocationHandler"/></param>
-               /// <returns>Proxy instance</returns>
-               public static object CreateProxy(Type theInterface, 
IInvocationHandler handler)
-               {
-                       return CreateProxy(new Type[] { theInterface }, handler 
);
-               }
-
-               /// <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");
-                       }
-                       if (interfaces.Length == 0)
-                       {
-                               throw new ArgumentException("Can't handle an 
empty interface array");
-                       }
-
-                       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);
-
-                       FieldBuilder handlerField = GenerateField( typeBuilder 
);
-                       ConstructorBuilder constr = GenerateConstructor( 
typeBuilder, handlerField );
-
-                       GenerateInterfaceImplementation( typeBuilder, 
interfaces, handlerField );
-
-                       Type generatedType = typeBuilder.CreateType();
-
-                       return Activator.CreateInstance( generatedType, new 
object[] { handler } );
-               }
-
-               /// <summary>
-               /// 
-               /// </summary>
-               /// <param name="typeBuilder"></param>
-               /// <param name="interfaces"></param>
-               private static void GenerateInterfaceImplementation( 
TypeBuilder typeBuilder, 
-                       Type[] interfaces, FieldBuilder handlerField )
-               {
-                       foreach(Type inter in interfaces)
-                       {
-                               GenerateInterfaceImplementation( typeBuilder, 
inter, handlerField );
-                       }
-               }
-
-               /// <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, FieldBuilder handlerField )
-               {
-                       if (!inter.IsInterface)
-                       {
-                               throw new ArgumentException("Type array expects 
interfaces only.");
-                       }
-
-                       Type[] baseInterfaces = inter.FindInterfaces( new 
TypeFilter( NoFilterImpl ), inter );
-
-                       GenerateInterfaceImplementation( typeBuilder, 
baseInterfaces, 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( method, 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( MethodInfo method, 
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.Ldtoken, method);
-                       ilGenerator.Emit(OpCodes.Call, 
typeof(MethodBase).GetMethod("GetMethodFromHandle"));
-
-                       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.IsEnum)
-                       {
-                               System.Enum baseType = (System.Enum) 
Activator.CreateInstance( type );
-                               TypeCode code = baseType.GetTypeCode();
-                               
-                               switch(code)
-                               {
-                                       case TypeCode.Byte:
-                                               type = typeof(Byte);
-                                               break;
-                                       case TypeCode.Int16:
-                                               type = typeof(Int16);
-                                               break;
-                                       case TypeCode.Int32:
-                                               type = typeof(Int32);
-                                               break;
-                                       case TypeCode.Int64:
-                                               type = typeof(Int64);
-                                               break;
-                               }
-
-                               return ConvertTypeToOpCode( 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 if ( type.Equals( typeof(Boolean) ) )
-                       {
-                               return OpCodes.Ldind_I4;
-                       }
-                       else
-                       {
-                               throw new ArgumentException("Type " + type + " 
could not be converted to a OpCode");
-                       }
-               }
-
-               public static bool NoFilterImpl( Type type, object criteria )
-               {
-                       return true;
-               }
-       }
-}
+ // 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;
+
+       using Apache.Avalon.DynamicProxy.Builder;
+
+       /// <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>
+       /// <remarks>
+       /// This proxy implementation currently doesn't not supports ref and 
out arguments 
+       /// in methods.
+       /// </remarks>
+       /// <example>
+       /// <code>
+       /// MyInvocationHandler handler = ...
+       /// IInterfaceExposed proxy = 
+       ///             ProxyGenerator.CreateProxy( new Type[] { 
typeof(IInterfaceExposed) }, handler );
+       /// </code>
+       /// </example>
+       public abstract class ProxyGenerator
+       {
+               private static IProxyBuilder m_builder = new ProxyBuilderImpl();
+
+               public static IProxyBuilder ProxyBuilder
+               {
+                       get { return m_builder; }
+                       set { m_builder = value; }
+               }
+
+               public static object CreateClassProxy(Type baseClass, 
IInvocationHandler handler)
+               {
+                       if (baseClass == null)
+                       {
+                               throw new ArgumentNullException("theClass");
+                       }
+                       if (baseClass.IsInterface)
+                       {
+                               throw new ArgumentException("'baseClass' must 
be a class, not an interface");
+                       }
+                       if (handler == null)
+                       {
+                               throw new ArgumentNullException("handler");
+                       }
+
+                       Type newType = ProxyBuilder.CreateClassProxy(baseClass);
+                       return CreateProxyInstance( newType, handler );
+               }
+
+               /// <summary>
+               /// Generates a proxy implementing all the specified interfaces 
and
+               /// redirecting method invocations to the specifed handler.
+               /// </summary>
+               /// <param name="theInterface">Interface to be 
implemented</param>
+               /// <param name="handler">instance of <see 
cref="IInvocationHandler"/></param>
+               /// <returns>Proxy instance</returns>
+               public static object CreateProxy(Type theInterface, 
IInvocationHandler handler)
+               {
+                       return CreateProxy(new Type[] {theInterface}, handler);
+               }
+
+               /// <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");
+                       }
+                       if (interfaces.Length == 0)
+                       {
+                               throw new ArgumentException("Can't handle an 
empty interface array");
+                       }
+
+                       Type newType = 
ProxyBuilder.CreateInterfaceProxy(interfaces);
+                       return CreateProxyInstance( newType, handler );
+               }
+
+               private static object CreateProxyInstance(Type type, 
IInvocationHandler handler)
+               {
+                       return Activator.CreateInstance(type, new object[] 
{handler});
+               }
+       }
+}
\ No newline at end of file

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to