Using CM within a class library

Topics: Bootstrappers & IoC, Getting Started
May 30, 2013 at 3:11 PM

I am currently working on a project and trying to apply the MVVM pattern with CM.

My project consists in a class library that does all the business logic and provides UserControls to be used by an external app.
My UserControls are standard WPF/XAML usercontrols using MVVM but I dont want the external app using them to have to use Caliburn or even know about the MVVM implementation.

My first try to use CM was to create a new instance of a bootstrapper inside my class library. The bootstrapper was derived from BootstrapperBase and overrides the SelectAssemblies method to include the class library assembly in the lookup process.

I can see through the debugger that everything initializes correctly, but nothing happens when the app starts. All i can see is the ClassName of a viewmodel that is supposed to be replaced by a corresponding view.

I tried to set up a console logger to see if there was any error from CM but nothing shows up.

(I have read this thread but it's not helping much since I already checked that my assembly was correctly added to the list).

Do you have any ideas about my problem ?

May 30, 2013 at 3:46 PM

I'm quite new to this myself, but I was trying to do as you were and had a similar problem when initialising views and VMs in a class library. This turned out to be down to the fact that AssemblySource did not contain the class library. If your bootstrapper is defined in the class library then the following line of code at the top of your configure function should solve the issue, or at least it did for me;
Hope this helps,

May 31, 2013 at 7:22 AM
Edited May 31, 2013 at 2:20 PM

Thanks for your answer.
The thing is, I have already provided my lib assembly and I could check it was in the AssemblySource with the debugger.

My override is the following :
protected override IEnumerable<Assembly> SelectAssemblies() {
    List<Assembly> baseAssemblies = new List<Assembly>(base.SelectAssemblies());
    Assembly thisAssembly = Assembly.GetAssembly(typeof(myInstance));
    if (!baseAssemblies.Contains(thisAssembly))
    return baseAssemblies;
I guess I'm missing something quite obvious because I can't figure out when the lookup process to return a View in place of a Viewmodel is supposed to happen.

EDIT : Just a wild guess because I've not yet fully understood the mechanism :
In a normal app, you would set the bootstrapper as a resource in the merged resource dictionnay. I imagine that is what allows CM to "attach" itself and correctly set up the View/Viewmodel bindings. Am I right (even remotely) ?
If so, a solution would be to add a resource dictionnary with the specified bootsloader and reference this resource dictionary in all the views ?

EDIT 2 : I tried to manually assign the view I wanted with the viewmodel by using the following syntax after viewmodel's creation :
Caliburn.Micro.View.SetModel(new myView(), myVMObject);
After that, at the moment the view should display, I get a trace in the debug output from CM, saying that the view has been bound to the viewmodel, I get multiple warnings saying that no action has been added for corresponding properties/methods (which is fine since I wasnt yet trying to use any actions).

But then, I still only see the viewmodel's name where the view is supposed to be displayed (not even a message from CM telling me it couldnt find a view or whatever...)