1

I'm trying to allow some navigation in Caliburn.Micro in a bit of a dynamic way (viewModels won't be known at design time).

This code obviously works

navigationService.UriFor<DatabasesViewModel>().Navigate();

However, with what I'm trying to do, I won't know the view model ahead of time. Instead I'll only have the Type of the view model.

I've been trying to use reflection to get the generic method, but I'm to able to get the UriFor method via GetMethod or GetMethods. Any ideas how this can be accomplished.

Tony Campney
  • 205
  • 1
  • 3
  • 7
  • Have you checked if it's an extension method? – Charleh Sep 02 '13 at 14:55
  • Yep, it's an extension `public static UriBuilder UriFor(this INavigationService navigationService)` - it's in type: `NavigationExtensions` so you could still go this route - obviously it won't resolve on the target object since technically it doesn't exist as a member – Charleh Sep 02 '13 at 14:57
  • possible duplicate of [How to use reflection to call generic Method?](http://stackoverflow.com/questions/232535/how-to-use-reflection-to-call-generic-method) – nawfal Jan 17 '14 at 16:06

1 Answers1

1

Your problem is not directly related to Caliburn.Micro but how to call generic methods with reflection in C#.

There are already quite a few and very good questions about this on SO: How do I use reflection to call a generic method?

However your case is a little bit special because the UriFor<T> method defined as an extension method by Caliburn in the NavigationExtensions class

So you need some extra steps and start from the NavigationExtensions type before you can call Navigate:

//Create the UriFor Method for your ViewModelType
var navigationExtension = typeof(NavigationExtensions);
var uriFor = navigationExtension.GetMethod("UriFor");
var genericUriFor = uriFor.MakeGenericMethod(yourViewModelType);

//Invoke UriFor: an instance of UriBuilder<T> is returned
var uriBuilder = genericUriFor.Invoke(null, new[] {navigationService});

//Create and Navigate on the returned uriBuilder
var navigateMethod = uriBuilder.GetType().GetMethod("Navigate");
navigateMethod.Invoke(uriBuilder, null);
Community
  • 1
  • 1
nemesv
  • 138,284
  • 16
  • 416
  • 359