Catel MVVM with CSLA Business Layer

Topics: Questions
May 9, 2012 at 7:18 PM

Hello,

recently I found this great Catel framework.
Previous I did my first MVVM steps using the Bxf framework from CSLA.
This worked, but is very limited.

Now I migrated my spike solution to use Catel at the Ui layer and I like it.
Unfortunately I lost the ViewModel features from CSLA when switching to the ViewModelBase classes from Catel.

Has anyone experiences with CSLA/Catel?
Should I better use the CSLA or Catel ViewModel implementation?
Is it even possible to use other VM base classes when doing MVVM with Catel?

One possible approach could be to build an intermediate class on top of Catels ViewModelBase, reinventing the features of CSLA.
But the CSLA VMBase is huge somehow...

I would be happy if someone can help me with this decision.
Thanks, Alexander.

 

Coordinator
May 9, 2012 at 8:28 PM

Great to hear that you found out the power of Catel :)

What view model features are you talking about? I am pretty sure the ViewModelBase in Catel is the most feature-rich available. If you know features that we haven't implemented, please let us know, then we will try to implement it.

May 10, 2012 at 8:09 PM

The CSLA ViewModelBase class is very special to the CSLA business layer.
You can look at it here:  http://www.lhotka.net/cslacvs/viewvc.cgi/core/trunk/Source/Csla.Xaml/ViewModelBase.cs?view=markup

Basically it features a Model<T> property where T is the actual business class type.
The view can bind direct to the models properties through this exposation.
Then there are methods to load the model data (sync and async) via DoRefresh() and BeginRefresh().
Saving the model data, adding and removing items if the model is a collection type and so on...

Additionally it provides bindable props telling what one can to with the model: CanSave, CanCancel, CanCreate, CanDelete and CanFetch.
It gets these informations from pulling the models state informations. 

Coordinator
May 11, 2012 at 9:09 AM

Interesting. We also provide some sort of models on the view model, but we allow multiple + they are not forced to a type. You can define as much models as you want on a view model using the Model attribute.

If you are using WPF, you can expose properties using the Expose attribute. This automatically checks whether a value is read only or write only or both, and behaves exactly like this.

The models are automatically reverted or accepted when the view model is saved, so basically the logic is all the same, but a but different in code (unfortunately for you).

May 11, 2012 at 4:22 PM

I tried to combine the Catel ViewModelBase and the CSLA ViewModel.
The CatelCslaViewModelBase derives from Catel.ViewModelBase and contains a CSLA.ViewModelBase.
Then a Model property forwards to the Csla.Model property.

Yes, it works in principle, but it is somehow complicated.....

Is it possible with Catel to use a ViewModel derived from something else as catels ViewModelBase?
For example, what would I loose when I use a DependencyObject based ViewModel?

I do not need the model features from Catel, CSLA has everything I need for this aspect.
Just wondering if I will get some other issues with the MVVM framework (like breaking the nested controls feature)!

alex.

May 11, 2012 at 6:25 PM

I just thought a bit further.

What if I derive my ViewModel classes from Csla.ViewModelBase and implement Catel.MVVM.IViewModel on them?
Most of the interfaces properties and methods could be routet to appropriate conterpart on the Csla.ViewModelBase implementation.

Will Catel.MVVM be well satisfied with such a solution?

alex. 

Coordinator
May 13, 2012 at 12:26 PM

That's exactly what you should do, implement IViewModel.

May 14, 2012 at 9:36 AM
Edited May 14, 2012 at 9:36 AM

Okay, I've tried this, but there are some pitfalls you have to circumnavigate.

First, to get the InterestedIn feature to get working,
I had to call internal methods on ViewModelManager using reflection to appropriate register the view.
The same is for calling the AuditingManager methods, but this is not so  important to me.

Unfortunately the ManagedViewModel casts to ViewModelBase to call ViewModelPropertyChanged,
ViewModelCommandExecuted and ViewModelEvent.
I would suggest to introduce an separate interface for these methods, so other IViewModel Implementations can participate on the InterestedIn feature.

 

    public interface INotifyableViewModel
    {
        void ViewModelPropertyChanged(IViewModel viewModel, string propertyName);
        void ViewModelCommandExecuted(IViewModel viewModel, ICatelCommand command, object commandParameter);
        void ViewModelEvent(IViewModel viewModel, ViewModelEvent viewModelEvent, EventArgs e);
    }

 

 

The UserControlLogic casts to ViewModelBase for child ViewModel registration.
So, I expect the great nested user control feature of Catel will not work with my IViewModel implementation.

To get this working, I recomment to introduce an additional interface IRelatedViewModel and let UserControlLogic use this abstraction:

 

    public interface IRelatedViewModel
    {
        void SetParentViewModel(IViewModel parent);
        void RegisterChildViewModel(IViewModel child);
    }

If I would incorporate such changes on my own, I would perfectly loose Catel upgrade options.But if there is no other way, I had to do this.... 
How Do you think about this?Alex.

Coordinator
May 14, 2012 at 5:36 PM

Sounds like a plan, I will create a work item for this and try to implement this.

See http://catel.codeplex.com/workitem/7132

Coordinator
May 16, 2012 at 9:39 PM

All implemented.

May 30, 2012 at 5:34 AM

Hello Geert,

sorry for my late reply.
It is great to see how enthusiastic this project is forced.
Thank you for the quick implementations of my suggestions.

I am working on a big project which is planned to has its first release in about three years. 
Until now I wrote an end-to-end spike solution  from DB to UI using all techniques we will use in this application.
I am pleased to see that Catel will be a part of it. 

Thanks, Alex.

Coordinator
May 31, 2012 at 4:11 PM

Great to hear :)

If you have any new feature request, just let us know! Or you can fork and send your updates yourself just like you did before.

Sep 10, 2012 at 8:19 PM

Hi Geert, Alex,

Awesome job on Catel Geert!

We too are looking into a LOB application using CSLA and Catel. Alex, I am wondering if you would like to share more details on your implementation.

Thanks, Martin

Sep 11, 2012 at 2:39 AM

Hi All,

I have same case using CSLA with dataobject and Catel with MVVM framework, if you share detail info on your implementation, it is best for me.

 

Thanks, Eric

Coordinator
Sep 11, 2012 at 11:37 AM

If Alex can share his CSLA code, we will create an extension for it so everyone can use it without any hassle.

Sep 15, 2012 at 4:53 PM

Hi Seaducer,
Hi ericyu67,

yes I think sharing this could help all of us.
My work on connecting the both worlds of CSLA and CATEL
is based on a somehow limited detail understanding of both of them.
So I expect some overall improvements on sharing it.

Unfortunately I am very busy this time and I'll need some days
to prepare the code along with a small sample.
Please be patient until then.

@Geert:
Are there any prerequisits to fulfill the code to be an catel extension?
At least there has to be references to the CSLA base and mvvm libraries.

@everyone:
I am uncertain about some overlapping features between Catel and CSLA.
Catel addresses the Validation and nested Usercontrol problems.
I am sure at some level, this is not needed in conjunction with CSLA.

The Model when using CSLA is a full featured thing as it provides full Validation features on its own.
In combination with the ViewModel based on CSLA.ViewModelBase the nested usercontrol problem seems to not exists to me.
Take a Model consisting of a Contact and a child object Address.
Create Views ContactView and AddressView, placing AddressView inside ContactView (nested).
Both ContactViewModel usese Contact as Model and AddressViewModel uses Address as Model.
When instancing the view, setting the DataContext of the nested AddressView control to the Model.Address property
will result in (ContactView->ContactViewModel->Contact) and (AddressView->AddressViewModel->Contact.Address).

The key is: Contact and Contact.Address are aware of each other at the Csla side. 
Changing some property on Contact.Address via the AddressView will trigger metadata on Contact, too.
So for example IsDirty on ContactViewModel is set to true, too.

Am I right, this mechanism will make Catels nested usercontrol feature needless in this situation?
Hope you understand what I mean...
Sorry if my explanations are incomprehensible caused by my lack of english knowledge.

Alex. 

Sep 16, 2012 at 11:57 AM

Okay, i've created a first version of a Csla extension for Catel.
Download here: http://root.startp.de/temp/Catel.CatelCsla_2012-09-16.7z
Unfortunately I cannot attach downloads to the discussion here... 

Coordinator
Sep 17, 2012 at 11:33 AM

Thanks, I have committed the first version of the CSLA extension. I need to include it in the build process and optimize it, but thanks for the code so far!

Coordinator
Sep 20, 2012 at 9:48 PM

Done. We released the first version via NuGet. Use this in the nuget shell:

Install-Package Catel.Extensions.CSLA -includeprerelease

Or simply search for "Catel.Extensions.CSLA" and make sure you include prerelease versions.

Please let us know what you think.

Oct 2, 2012 at 10:57 PM

Hi Alex,

I also use CSLA model with Catel ViewModel. I am very impressed with Geert & Catel.

Unfortuntely I have not had the time I would have liked to fully understand Catel & CSLA and I have basically done 'just enough' to get  the desired results.

How does your code work with complex nested models which include 'one to many' relationships and multiple nesting levels?

EG

Models

  • Account contains 1 or more Clients.
  • Client contains 1 or more ClientContact (eg phone, email). Includes Client specific data (eg priority, description)
  • ClientContact contains nested Contact (generic / common contact data)

ViewModels

  • AccountVM
    • contains Account Model
    • exposes list of Clients
  • ClientVm
    • contains Client Model
    • exposes list of ClientContacts
  • no need for ClientContact or Contact VMs as both classes are
    • relatively simple
    • only used in lists

Views

  • AccountView
    • includes list of Clients
    • includes ClientView (for selected Client). Allows editing of Client  data
  • ClientView
    • includes list of ClientContacts
    • users may edit ClientContact (and nested Contact) details directly from list.

Some issues:

  • AccountView:
    • Ensuring changes made to Client objects are not lost as user navigates through the Client list
    • Ensuring changes made to Client Objects make the AccountVm dirty
    • Saving the AccountVM should not trigger saves of any contained VMs as CSLA handles saving of nested Models
  • ClientView
    • Ensuring changes to ClientContact objects make the ClientVm object dirty

 

Oct 3, 2012 at 10:09 AM

Hello kosta_t,

unfortunately my answer will not satisfy you...
My progress using CSLA/CATEL is using it with ReadOnly business objects for displaying only.
Your issues address writeable BOs.

But in a few weeks, I have to solve these problems, too.. :-)

Besides, I have some ideas how it should work.
For maximum business layer compatibility, I've used the Csla ViewModelBase as base for my viewmodel classes.
As you can read in this thread, there were some modifications done to Catel to support non-catel viewmodels.

In my opinion the nested user controls problem simply does not exist when using a Csla based model.
This is because the model is very aware of the complete object graph state.
Modifying properties on containing (child) BOs through nested viewmodels will trigger state changes
to the upper layers.
Therefore, Catel does not need to address these issues at all.
I do not know for now if you can deactivate the Catel logic addressing this.
The same is true for the Saving of child objects, which is fully done by Csla and Catel just do not have to care about it.

Similar thoughts I have written on September, 15 on this thread.
Unfortunately no one has picked up my questions from this post so far...

Using Catel with Csla is very new.
I do not know about anybody else who has done this previously.
Catel is not mentioned on the Csla forums as well.
I think there has to be done some more intense developing until everything will work as it should.
By providing the Catel.Csla extension, Geert has done a great step towards supporting Csla with Catel.
But I think this extension has to be fine tuned to solve the issues you wrote about. We'll see....

regards, Alex.

Coordinator
Oct 3, 2012 at 10:14 AM

Good that you are helping each other out here. 

Nested user controls is not solved by CSLA. You will still need to convert a model into a view model at runtime for nested user controls. Catel will call IEditableObject interfaces when something is registered as model. So, basically, this can be done:

1) Create a catel view model

2) Register the CSLA model as model using the ModelAttribute

3) Be happy

Unfortunately there was a bug which I have fixed (it forced all models to be a DataObjectBase), but not released a new version yet. Since I am extremely busy at the moment, I don't expect a new release until this weekend.

Oct 5, 2012 at 9:55 PM

Hi Alex,

Unfortunately I am insanely busy atm, but I will try to find some time to look at your extension.

As I said earlier I am not using the CSLA ViewModelBase. Instead I have created some of my own ViewModelBase classes, dervide from catels VM & added some interfaces and a couple of user controls to provide a 'standard' user interface (eg add/save/delete/refresh/find model objects, add/remove objects from list, update user control when model is dirty),

My ViewModels, then derive from my 'DbViewModelbase' and implement some interfaces for the ui controls. Currently this involves using a bit of cut and paste to create a new model.

At some stage I want to sit back & do a code review so that I can turn my code into a usable library. Hopefully I can find a good mix of my & your ideas.

Geert, I agree the nested user control problem is not solved by CSLA. In fact (as per my previous post) CSLA can actually result in hard to debug issues hen using nested models.