Bug 2695 - System.MissingMethodException thrown from Type.InvokeMember when trying to invoke WCF channel method
Summary: System.MissingMethodException thrown from Type.InvokeMember when trying to in...
Status: RESOLVED NOT_ON_ROADMAP
Alias: None
Product: Android
Classification: Xamarin
Component: BCL Class Libraries ()
Version: 2.0
Hardware: PC Windows
: --- normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2011-12-29 23:11 UTC by Felix Collins
Modified: 2012-01-03 15:21 UTC (History)
2 users (show)

Tags:
Is this bug a regression?: ---
Last known good build:


Attachments
Repro solution with console and android projects (14.37 KB, application/zip)
2011-12-29 23:11 UTC, Felix Collins
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
RESOLVED NOT_ON_ROADMAP

Description Felix Collins 2011-12-29 23:11:05 UTC
Created attachment 1113 [details]
Repro solution with console and android projects

System.MissingMethodException thrown from Type.InvokeMember when trying to invoke WCF channel method

Attached solution has two projects. Console project invokes method (not that anything happens) but Android project fails to find method.
Comment 1 Jonathan Pryor 2012-01-02 14:32:47 UTC
Mono for Android does not provide the full WCF stack of desktop .NET, it provides a (beta-level) implementation of the Silverlight WCF stack. I don't know if the desktop vs. Silverlight differences come into play here, but desktop Mono uses the same WCF implementation as Mono for Android, and the console app fails in the same way on desktop mono:

> Unhandled Exception: System.MissingMethodException: Cannot find method BeginTestInvokeMember.
  at System.MonoType.InvokeMember (System.String name, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object target, System.Object[] args, System.Reflection.ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, System.String[] namedParameters) [0x00000] in <filename unknown>:0 
>   at System.Type.InvokeMember (System.String name, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object target, System.Object[] args) [0x00000] in <filename unknown>:0 
>   at ConsoleApplication1.Program.Main (System.String[] args) [0x00000] in <filename unknown>:0 

Even if Mono's WCF implementation were complete (which it isn't), I doubt that relying on implementation details would work, and your use of Reflection and Type.InvokeMember() would likely qualify.

Finally, if you avoid the Reflection use and use the interface directly, it works on Mono for both the desktop and Mono for Android builds:

	tester.BeginTestInvokeMember (x => {}, null);

Finally, if you simply must rely on Reflection, using the interface type instead of the channel type works:

	typeof(ITestInvokeMember).InvokeMember (
			"BeginTestInvokeMember",
			BindingFlags.Public | BindingFlags.InvokeMethod | BindingFlags.Instance,
			null,
			tester,
			new object[]{null,null}
	);
Comment 2 Felix Collins 2012-01-03 15:21:51 UTC
That makes perfect sense. We build a console version of our app (for testing) as well as mobile versions. I guess I should be compiling the console version against Mono to have better compatibility. 

You are right that I should have been reflecting against the interface which I was choosing the  methods from so it is surprising that the way I was doing it worked at all. I would agree that it is correct to call that an implementation detail.  

The reason I was using reflection was to reduce duplication of code in a wrapper. In the end I changed to passing delegates to the wrapper implementation (As opposed to method names). This is faster, safer and easier to debug.

Thanks for looking into this so fast and I'm sorry I wasted your time!