New Posts New Posts RSS Feed: Caliburn can't locate an view because the recomposition isn't done yet ?
  FAQ FAQ  Forum Search   Calendar   Register Register  Login Login

Caliburn can't locate an view because the recomposition isn't done yet ?

 Post Reply Post Reply
Author
Walid View Drop Down
Senior Member
Senior Member
Avatar

Joined: 14-Nov-2010
Posts: 161
Post Options Post Options   Quote Walid Quote  Post ReplyReply Direct Link To This Post Topic: Caliburn can't locate an view because the recomposition isn't done yet ?
    Posted: 07-Mar-2012 at 4:21pm
Hi,

I went into what I think is a bug but I don't know if it's on devforce/cocktail side or caliburn side.

The applications works with many plugins, each one of these plugins is located in a different XAP.
Each XAP has a class which implement the interface ITest in order to do some initialization.

When the user click on a button, the application loads those XAP and call the method Initialize from ITest

Exemple of Initialize method :
        public void Initialize(ICollection<object> list)
        {
            list.Add(new TestViewModel());
        }
in the ShellView, I have a list of ITest which is injected by MEF with Allowrecomposition = True.
When the collection change, I call the method Initialize on all the ITest instance in my list.

the list parameter fo the Initialize method is in fact an ObservableCollection from my shellviewmodel which is binded in to an itemcontrol in the shellview.

The TestViewModel class has no code but has  a TestView associated which only show the text "Hello Devforce". 

when I start the application, and click on the button to download the XAP I get the message "Cannot find view for ...." but this View exist !!

I added a second button which, after the XAP been downloaded, will call Composition.GetInstances<ITest> and call the Initialize method on all the intances. 
This time it works fine, caliburn bind and show the view .


Here is what I did notice :
1st case : when I enter in the Initialize method because of the recomposition
The  AssemblySource.Instance list from caliburn has no trace of anything from the XAP I just downloaded.
2nd case : when I enter in the Initialize method after the GetInstances<ITest> 
The  AssemblySource.Instance list has trace of the viewModel, View ...

In the ViewLocator of Caliburn, it try to find the View in the AssemblySource.Instance. If it doesn't find it it show the message "can't find view for ....". So that explain why it doesn't' works with the recomposition 

But to me it looks like a bug, the AssemblySource.Instance should have trace of everything yet since it did find the ITest Export.
Since I don't really understand who refresh this list because Devforce does the recomposition, can you enlight me on this "bug" ?

Here is a test application which reproduce the problem


Regards,

Walid.
Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 07-Mar-2012 at 6:37pm
Walid,
I will take a look at it to see what's going on. Cocktail should be refreshing the AssemblySource upon recomposition. I'll get back to you with my findings.
Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 07-Mar-2012 at 7:44pm
Walid,
The bug is in your application. AddXap is an asynchronous operation with many steps. When your ListTests_CollectionChanged gets called, the process is only at the MEF recomposition step, but AddXap is not yet done with updating the AssemblySource. You need to wait for AddXap to complete before going through the collection and call Initialize.
 
Get rid of ListTests_CollectionChanged and change the Click method like follows and it all works fine.
 
        public IEnumerable<IResult> Click()
        {
            yield return Composition.AddXap("DownloadMe.xap");
 
            foreach (var test in ListTests)
            {
                test.Initialize(Tests);
            }
        }
Back to Top
Walid View Drop Down
Senior Member
Senior Member
Avatar

Joined: 14-Nov-2010
Posts: 161
Post Options Post Options   Quote Walid Quote  Post ReplyReply Direct Link To This Post Posted: 08-Mar-2012 at 12:34am
Hi,

Thanks for your answer marcel.


I agree with your comment but in our real application things are a little bit more complicated (maybe because of bad design ?).

In the bootstrapper I handle the LoggedInMessage from the LoginManager and this is where I load the initial XAPs. At that time, the ShellView already exist with his collection using recomposition. 
I could maybe handle the LoggedInMessage in the shellview and does like you say and get rid of the recomposition but in the future we might be able download other XAP from different screens and some might own some ITest implementation.
So if I do like you say I would not be able to have recomposition on those one. 

For information, this collection in the shellview is a collection of menu item. Each XAP we download can then add some new menu item to the application.


So I really need to use the recomposition on this point.


Regards,


Back to Top
mgood View Drop Down
IdeaBlade
IdeaBlade
Avatar

Joined: 18-Nov-2010
Location: Emeryville, CA
Posts: 583
Post Options Post Options   Quote mgood Quote  Post ReplyReply Direct Link To This Post Posted: 08-Mar-2012 at 4:02am

You can still use recomposition, but the point is you have to wait for the XAP load to finish before doing anything with the new parts. If the part of the code that loads the XAP and the part of the code that needs to update the UI based on the new stuff that came in are far apart, then you can simply publish a message to the EventAggregator when the loading of the XAP is done to signal the part of the code that needs to update the UI, that new parts have arrived and it's safe to use them.

The parts would already be there in the respective collections, thanks to recomposition, but the application wouldn't touch them until it receives the all-clear message from the EventAggregator.
Back to Top
Walid View Drop Down
Senior Member
Senior Member
Avatar

Joined: 14-Nov-2010
Posts: 161
Post Options Post Options   Quote Walid Quote  Post ReplyReply Direct Link To This Post Posted: 08-Mar-2012 at 5:42am
ok thank you
Back to Top
 Post Reply Post Reply

Forum Jump Forum Permissions View Drop Down