using System; using System.Diagnostics; using System.Reflection; using System.Runtime.InteropServices; using System.Globalization; internal class Utils { internal static Exception NotImplemented(string message) { Console.WriteLine(message); return new Exception(message); } } public class MyMethodInfo : MethodInfo { string _name; public MyMethodInfo(string name) : base() { _name = name; } #region abstract overrides // Unimplemented methods public override ICustomAttributeProvider ReturnTypeCustomAttributes { get { throw Utils.NotImplemented("In MyMethodInfo.ReturnTypeCustomAttributes"); } } public override MethodInfo GetBaseDefinition() { throw Utils.NotImplemented("In MyMethodInfo.GetBaseDefinition"); } public override MethodImplAttributes GetMethodImplementationFlags() { throw Utils.NotImplemented("In MyMethodInfo.GetMethodImplementationFlags"); } public override RuntimeMethodHandle MethodHandle { get { throw Utils.NotImplemented("In MyMethodInfo.MethodHandle"); } } public override MethodAttributes Attributes { get { throw Utils.NotImplemented("In MyMethodInfo.Attributes"); } } public override Type DeclaringType { get { throw Utils.NotImplemented("In MyMethodInfo.DeclaringType"); } } public override Type ReflectedType { get { throw Utils.NotImplemented("In MyMethodInfo.ReflectedType"); } } public override bool IsDefined(Type a, bool b) { throw Utils.NotImplemented("In MyMethodInfo.IsDefined"); } public override object Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) { throw Utils.NotImplemented("In MyMethodInfo.Invoke"); } // Methods that need to be implemented for the scenario to work public override ParameterInfo[] GetParameters() { return new ParameterInfo[0]; } public override object[] GetCustomAttributes(bool a) { return new object[0]; } public override object[] GetCustomAttributes(Type a, bool b) { return new object[0]; } public override string Name { get { Console.WriteLine("In MyMethodInfo.Name.get({0})", _name); return _name; } } #endregion } public class ManagedIDispatch : IReflect { static int _Count = 0; int _index; MethodInfo[] _methodInfos; bool _getMethodsDone = false; public ManagedIDispatch() { _index = _Count++; _methodInfos = new MethodInfo[] { new MyMethodInfo("foo"), // A method on all instances new MyMethodInfo("bar" + _index), // A unique method name for all instances new MyMethodInfo("raiseException") // A method that throws a managed exception }; } // Just to show that InvokeMember needs to explicitly handle the method named "[DISPID=0]" [DispId(0)] public object DefaultMethod() { throw Utils.NotImplemented("This is unreachable"); } static string GetArgs(object target, object[] args) { string str = ""; str += target.ToString(); foreach (object a in args) { str += ", " + a; } return str; } #region IReflect Members // Unimplemented methods public FieldInfo GetField(string name, BindingFlags bindingAttr) { throw Utils.NotImplemented("In ManagedIDispatch.GetField"); } public MemberInfo[] GetMember(string name, BindingFlags bindingAttr) { throw Utils.NotImplemented("In ManagedIDispatch.GetMember"); } public MethodInfo GetMethod(string name, BindingFlags bindingAttr) { throw Utils.NotImplemented("In ManagedIDispatch.GetMethod"); } public MethodInfo GetMethod(string name, BindingFlags bindingAttr, Binder binder, Type[] types, ParameterModifier[] modifiers) { throw Utils.NotImplemented("In ManagedIDispatch.GetMethod"); } public PropertyInfo GetProperty(string name, BindingFlags bindingAttr, Binder binder, Type returnType, Type[] types, ParameterModifier[] modifiers) { throw Utils.NotImplemented("In ManagedIDispatch.GetProperty"); } public PropertyInfo GetProperty(string name, BindingFlags bindingAttr) { throw Utils.NotImplemented("In ManagedIDispatch.GetProperty"); } public Type UnderlyingSystemType { get { throw Utils.NotImplemented("In ManagedIDispatch.UnderlyingSystemType"); } } // Methods that need to be implemented for the scenario to work public FieldInfo[] GetFields(BindingFlags bindingAttr) { return new FieldInfo[0]; } public MemberInfo[] GetMembers(BindingFlags bindingAttr) { return new MemberInfo[0]; } public PropertyInfo[] GetProperties(BindingFlags bindingAttr) { return new PropertyInfo[0]; } public MethodInfo[] GetMethods(BindingFlags bindingAttr) { Console.WriteLine("In ManagedIDispatch.GetMethods (_getMethodsDone={0})", _getMethodsDone); // dynFoo is a method that is not always present if (_getMethodsDone) { MethodInfo[] methods = new MethodInfo[_methodInfos.Length + 1]; _methodInfos.CopyTo(methods, 0); methods[_methodInfos.Length] = new MyMethodInfo("dynFoo"); return methods; } else { _getMethodsDone = true; return _methodInfos; } } public object InvokeMember(string name, BindingFlags invokeAttr, Binder binder, object target, object[] args, ParameterModifier[] modifiers, CultureInfo culture, string[] namedParameters) { Console.WriteLine("In ManagedIDispatch.InvokeMember({0} : {1})", name, GetArgs(target, args)); switch (name) { case "[DISPID=0]": return this; case "raiseException": throw new Exception("raiseException has been invoked"); case "foo": return "foo-return"; case "dynFoo": Debug.Assert(_getMethodsDone); return "dynFoo-return"; default: if (name == ("bar" + _index)) return "bar-return"; throw Utils.NotImplemented("This is unreachable"); }; } #endregion } [ComVisible(true)] [Guid("2E5059A6-D607-42ab-85C2-B064E0A09074")] public class TestFactory { public ManagedIDispatch GetManagedObject() { return new ManagedIDispatch(); } [DispId(0)] public object DefaultMethod() { return this; } }