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

Sergio picture Sergio · Jul 4, 2013 · Viewed 9.2k times · Source

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

Answer

Charleh picture Charleh · Jul 4, 2013

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