Caliburn.Micro can't match View and ViewModel from different assemblies
Asked Answered
I

2

11

I just started with Caliburn.Micro.

I'm trying to bootstrap my simple sample solution placing the ShellView (usercontrol) in an Test.App assembly, and the ShellViewModel in the Test.ViewModel assembly.

What i get is a window with the following text: "Cannot find view for Caliburn.Test.ViewModel.ShellViewModel".

But if I move the ViewModel to the .App assembly, it works perfectly.

this is the Bootstraper in the Caliburn.Micro.Test assembly (executable):

namespace Caliburn.Micro.Test
{
    public class AppBootstrapper : BootstrapperBase
    {
        SimpleContainer container;

        public AppBootstrapper()
        {
            this.Start();
        }

        protected override void Configure()
        {
            container = new SimpleContainer();

            this.container.Singleton<IWindowManager, WindowManager>();
            this.container.Singleton<IEventAggregator, EventAggregator>();
            this.container.PerRequest<IShell, ShellViewModel>();
        }

        protected override object GetInstance(Type service, string key)
        {
            var instance = this.container.GetInstance(service, key);
            if (instance != null)
                return instance;

            throw new InvalidOperationException("Could not locate any instances.");
        }

        protected override IEnumerable<object> GetAllInstances(Type service)
        {
            return this.container.GetAllInstances(service);
        }

        protected override void BuildUp(object instance)
        {
            this.container.BuildUp(instance);
        }

        protected override void OnStartup(object sender, System.Windows.StartupEventArgs e)
        {
            this.DisplayRootViewFor<IShell>();
        }

        protected override IEnumerable<System.Reflection.Assembly> SelectAssemblies()
        {

            var assemblies = new List<Assembly>()
            {
                Assembly.GetExecutingAssembly(),
                Assembly.Load("Caliburn.Micro.Test.ViewModel"),
            };

            return assemblies;
        }
    }
}

this is my ViewModel in the Caliburn.Micro.Test.ViewModel assembly (class library):

namespace Caliburn.Micro.Test.ViewModel
{
    public interface IShell
    {
    }

    public class ShellViewModel : IShell
    {
    }
}

Can you help me solve my problem, please? Thank you! :D

Integral answered 4/7, 2013 at 14:50 Comment(1)
Have you overridden SelectAssemblies? You need to provide CM all assemblies that contain viewsLashoh
L
20

Check that you have selected your assembly for CM by overriding SelectAssemblies in your bootstrapper.

The documentation here has an example:

http://caliburnmicro.codeplex.com/wikipage?title=Customizing%20The%20Bootstrapper

protected override IEnumerable<Assembly> SelectAssemblies()
{
    return new[] {
        Assembly.GetExecutingAssembly()
    };
}

Edit:

Ok not only do you need to select assemblies to tell CM where to look - it sounds like in your case your VMs and your Views may be in different namespaces since you have them in separate libraries. You can use the same root namespace in both libraries and the standard view resolution should work fine - however, you need to make sure you have selected the assembly in the bootstrapper in order to tell CM what assemblies to try to resolve views in.

If you want to put your views/VMs in different namespaces for some reason or another, you need to customise the logic that CM uses to resolve a view. It uses naming conventions to locate a View based on the fully qualified type name of the viewmodel (or vice-versa if you are using a view-first approach)

I suggest reading up on the introductory documentation:

http://caliburnmicro.codeplex.com/wikipage?title=Basic%20Configuration%2c%20Actions%20and%20Conventions&referringTitle=Documentation

Then follow it through. If you want to skip directly to naming conventions, check out this particular page:

http://caliburnmicro.codeplex.com/wikipage?title=View%2fViewModel%20Naming%20Conventions&referringTitle=Documentation

and

http://caliburnmicro.codeplex.com/wikipage?title=Handling%20Custom%20Conventions&referringTitle=Documentation

Lashoh answered 4/7, 2013 at 16:9 Comment(8)
what do you mena with "CM" ? anyway, i read thats to be done for the assemly where it has to search for the Views, but the Views are in the same assembly of the Bootstrapper, the ViewModels are in another. Anyqay, can you show an example of an import? Thanks!Integral
Ah I misread, so you have views in a different assembly than vms, you need to provide logic for the viewlocator to search the additional namespace as it won't know to look there by default. Ill update my answerLashoh
And when I say CM I mean Caliburn Micro :)Lashoh
ok but i just started with CM so can u explain me more in detail please, i really dont know anything about itIntegral
Updated my answer - I'd recommend some reading up first, it really shouldn't take more than a few hours to get acquainted with the simpler stuff and a couple of days to get comfortable with the restLashoh
I edited the main post with the edits I did now, but it still doesn't work :( Yeah, I read the documentation, and I got to the Bootstrapper configuration chapter, and it's there that I'm stuck in trying to make it work in separated assemblies.Integral
I think i got it but where should I access the View/Model Locator to configure it? I think I have to override a method of the Bootstrapper but which? Thank youIntegral
Excellent - my issue was similar, except the Bootstrapper was in a referenced DLL, so I needed to say Assembly.GetEntryAssembly().Gish
I
7

Solved thanks to this article http://www.jerriepelser.com/blog/split-views-and-viewmodels-in-caliburn-micro/

EDIT: since you integrated your reply with mine I change the accepted answer to be yours.

Integral answered 4/7, 2013 at 19:53 Comment(2)
link is dead. domain name has expired. :(Arnica
I fixed the link, see jerriepelser.com/blog/the-killing-of-a-rockstarUnfailing

© 2022 - 2024 — McMap. All rights reserved.