WP7: Navigating to page in another assembly, ViewModelLocator problem

Aug 9, 2011 at 9:11 AM
Edited Aug 9, 2011 at 9:18 AM

Using the Caliburn.Micro version 1.2, I'm trying to navigate to a page which lives inside an another assembly. The navigation is done like this:

navigation.Navigate(new Uri("/Module1;component/MyPage.xaml" UriKind.Relative));

Where the navigation-field is type of INavigationService.

I'm having some problems with the ViewModelLocator though, because by default it seems to only try to locate the view models which live inside the executing assembly. I've tried to go around this problem but WP7's platform seems to have restricted access to all the required functions. So my question is, is it possible to get the ViewModelLocator to work for a page which isn't inside the executing assembly? At the moment

I first tried to override the SelectAssemblies, but the following code doesn't work, because we're not permitted to access the Assembly.Load:

protected override IEnumerable<Assembly

> SelectAssemblies() { 

 return new[] { Application.Current.GetType().Assembly, Assembly.LoadFrom("Module1.dll"


 )}; }



I then thought about modifying the code in LocateTypeForViewType so that it goes through all the assemblies inside the current AppDomain instead of AssemblySource, but WP7 version of .NET is missing the GetAssemblies-method.

I found all the assemblies from the Deployment.Current.Parts but the assemblies there aren't of type Assembly but something called AssemblyPart. And I suppose there's no way to transform an AssemblyPart into an Assembly.

Without modifying anything and just using the base Caliburn.Micro 1.2, I'm getting the following log-messages:

View Model not found. Searched: Module1.MyPageViewModel, .
View Model not found. Searched: Module1.MyPageViewModel, Module1.IMyPageViewModel.

I'm using the SimpleContainer and I have registered the view models like this:





 Btw. Thanks for the framework. It's just an excellent piece of code.

Aug 9, 2011 at 6:22 PM

You have to make sure that the ViewModel is registered into the IoC container, since the ViewModelLocator delegates actual VM instantiation to it.
You can check the correct registration calling IoC.Get<YourVMType>().
It seems a little strange, though, since WP7 bootstrapper should take care to conventionally register all VM it can find in the assemblies registered into AssemblySource (which you seem to be doing right with SelectAssemblies override).

Please, let me know the result of registration check.
If you have the chance to put together a little repro, I'll have a look at it and try to figure out the problem.

Aug 15, 2011 at 5:32 PM

Thanks for the reply and sorry that is has taken so long for me to get back to you. I'm in the middle of a holiday and unfortunately my example code is located on my another computer, so I can't provide an example until next week.

And sorry for not being clear in my original post. My code example in the original post where I override the SelectAssemblies doesn't work. WP7-platform doesn't allow one to call the Assembly.Load-method. So even though calling IoC.Get<MyVm> would propably work (I can't check), the ViewModelLocator wouldn't ever call that code, because LocateTypeForViewType does not know about the MyVm-type.

Aug 15, 2011 at 7:29 PM

Got it. I googled around a bit, and it seem that assembly loading is explicitly disallowed for security reasons (see, for example: http://social.msdn.microsoft.com/Forums/en-US/windowsphone7series/thread/644ad5ca-29b0-488d-abd8-0d1c1469b0d4/).
I would try forcing an assembly load indirectly through Type.GetType(string), passing a full type name; I didn't test it, so I'm not sure it would work.

How about statically binding the modules in the Main application? Would it be applicable (aside from code cleanliness consideration)?