4
votes

I'm using Caliburn.Micro bootstrapper here:

https://gist.github.com/1127914

Everything works if I keep all views and viewmodels in the same project as the bootstratpper.

But I wanted to push the Views and ViewModels folder to another assembly/project, I do, change the namespaces, update the bootstrapper to find that viewmodel. Now when I run I get the error about

"No component for supporting the service MVVMBook.ViewModules.ViewModels.MainViewModel was found"

on this part of the bootstrapper:

return string.IsNullOrWhiteSpace(key)
               ? _container.Resolve(service)
               : _container.Resolve(key, service);

Obviously it is not able to wire up the ViewModel, even though the VM is set as the generic parameter to the Bootstrapper:

 public class CastleBootstrapper : Bootstrapper<MainViewModel>

The naming convention I'm using is a folder called Views and a Folder called ViewModels and the files are MainView.xaml and MainViewModel.cs

Where can I tell it to look in this assembly?

Also added this piece to the bootstrapper as it was recommended when views and viewmodels are in a separate assembly but didn't resolve the issue:

// needed if views and viewmodels are in a seperate assembly
  protected override IEnumerable<Assembly> SelectAssemblies()
  {
     return new[]
               {
                  Assembly.GetExecutingAssembly()
               };
  }
1

1 Answers

7
votes

Your ViewModel wasn't found because it wasn't registered. The ApplicationContainer class which accompanies the bootstrapper has a RegisterViewModels method which looks like this:

private void RegisterViewModels()
{
    Register(AllTypes.FromAssembly(GetType().Assembly)
                    .Where(x => x.Name.EndsWith("ViewModel"))
                    .Configure(x => x.LifeStyle.Is(LifestyleType.Transient)));
}

This registers only ViewModels in the assembly where the ApplicationContainer is located.

I suppose you pasted those classes in your project so you can modify them. If that is the case you could modify the app containers RegisterViewModels or modify CastleBootstrapper and override the Configure() method like this:

protected override void Configure()
{
     _container = new ApplicationContainer();
     _container.AddFacility<TypedFactoryFacility>();
     _container.Register(AllTypes.FromAssembly(typeof(MainViewModel).Assembly)
         .Where(x => x.Name.EndsWith("ViewModel") || x.Name.EndsWith("View"))
         .Configure(x => x.LifeStyle.Is(LifestyleType.Transient)));
}

The above will register all view-models and views. For Caliburn to locate the views properly, update the SelectAssemblies() method:

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

More on Castle.Windsor can be found here http://stw.castleproject.org/Windsor.MainPage.ashx