I've put an early release of 3.8.0 online for download.
The primary areas of focus are in Csla.Silverlight and Csla.Wpf, and there are breaking changes to the XAML controls in those namespaces, so check the change logs for details. I've been focusing (so far) on InvokeMethod and PropertyStatus.
On the Silverlight side there's also a new ViewModel base class to help create viewmodel objects, and an enhancement to make CslaDataProvider.ObjectInstance bindable so you can probably use CslaDataProvider as a viewmodel object. I also added a new trigger action called Execute which offers a more modern (though more verbose) way to do something like InvokeMethod.
Also it occurs to me that CSLA .NET for Silverlight probably won't build if you don't have Expression Blend 3 installed. I'll have to figure out a solution for this - but in the meantime, if you don't have Blend 3 installed you'll need to comment out or remove the Csla.Silverlight.Execute class.
Finally, on the Silverlight side, MobileFormatter now defaults to using binary XML to serialize objects. This should reduce the memory footprint for n-level undo, and should reduce the size of the byte stream that goes over the data portal. There is a config option you can set to get the text XML serialization if you need that for some reason.
Unfortunately I haven't had time to do any testing with the binary XML in terms of perf or memory footprint, so I don't know if it makes a big difference or not. I got it implemented and working and that's about it...
I'm on vacation the week of August 17, so if there are any major issues just remember that this is a very early release and it will continue to change.
In fact - my primary motivation for putting this out right now is to get feedback and input, especially around the changes to InvokeMethod, PropertyStatus, the ViewModel base class and the Execute trigger action. If you have ideas on how these can be improved for the Silverlight 3 world I am eager to hear them!
Paul,
Did you notice any measurable difference on the binary xml implementation? Is it something you can share for 3.7? I'm looking for some quickfix speed improvements but not sure if I want to put out Alpha software.
Thanks
jack
Yes, my work in 3.8 was to make the actual object graph
serialization use the binary format. That isn’t something you can control
or affect through the WCF configuration.
If you care about the details, you should read my Silverlight
blog posts about the MobileFormatter and how it was designed. At a high level
it works like this:
1.
The business objects’ data is copied into a set of DTOs
2.
The DTOs are serialized using the DataContractSerializer
3.
The resulting byte array is stored in memory, or sent over WCF
or whatever
4.
If it is sent over WCF, then obviously WCF serializes the
message – including the byte array
So if you configure WCF to use binary encoding that affects step
4 in the process. I haven’t done thorough testing here, but I suspect you’ll
see a 40-60% reduction of the data stream over the wire by doing this.
Of course you can also implement compression like I show in the
video series, and that’ll radically reduce the size of the data stream
over the wire – and the WCF config change will still shrink that by
around half. So the WCF thing is a big deal.
My work in 3.8 is to affect step 2 in the process. The exact
impact of this is difficult to know, and I didn’t have time to do any
real testing. This change really affects the way the business object data is
encoded, and so should have a pretty big impact, but probably more like 20-30%
I would guess. Less than the use of compression or the WCF change.
I suspect that most people will want to have CSLA use the binary
encoding for step 2 so that’s the default. I also suspect that most
people will configure WCF to use the binary encoding. And that they’ll
use compression. The three things combined should produce a really nice overall
result.
Rocky
From: paupdb
[mailto:cslanet@lhotka.net]
Sent: Tuesday, August 18, 2009 7:07 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] CSLA .NET 3.8.0 alpha 1 available
Jack,
In my case, I had already implemented a custom WcfProxy class back in Csla 3.6
to include zip compression/decompression code using the SharpZipLib library.
So the subsequent move to using binary encoding for Wcf didn't reduce my object
graphs by that much...although I plan to remove my explicit zip/unzip code to
see how pure binary encoding goes.
That said I think Rocky has taken the binary xml even further into the framework
itself for undo etc, so I'm expecting more reduction in terms of memory usage
as well as transport objects with 3.8
Right now I have two simple experimental projects (one for SL,
one for WPF) that I’ve been using. They aren’t in svn, but perhaps I should add
them to increase visibility.
From: Jack
[mailto:cslanet@lhotka.net]
Sent: Tuesday, August 25, 2009 10:08 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] CSLA .NET 3.8.0 alpha 1 available
Rocky,
Which sample application, if any of them, are you trying out these changes in?
Thanks
jack
Rocky,
When you put out Alpha 2 will you add your samples?
Thanks
jack
From: Rockford Lhotka [mailto:cslanet@lhotka.net]
Sent: August-25-09 9:19 AM
To: jaddington@alexandergracie.com
Subject: RE: [CSLA .NET] CSLA .NET 3.8.0 alpha 1 available
Right now I have two simple experimental projects (one for SL,
one for WPF) that I’ve been using. They aren’t in svn, but perhaps I should add
them to increase visibility.
From: Jack [mailto:cslanet@lhotka.net]
Sent: Tuesday, August 25, 2009 10:08 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] CSLA .NET 3.8.0 alpha 1 available
Rocky,
Which sample application, if any of them, are you trying out these changes in?
Thanks
jack
One thing I'm looking at doing with ViewModel<T> is creating two classes.
ViewModelBase<T> - implements the Model property, public Can___() methods like CanSave(), and protected DoSave(), DoCancel(), etc. In other words, this class exposes no public verb/action/command methods.
ViewModel<T> - inherits from ViewModelBase and adds public verbs like Save(), Cancel(), etc. for use by InvokeMethod or the new Invoke trigger action.
The idea is that ViewModelBase can be used as a base class if you are using some other UI framework's commanding model. There are so many out there, and Microsoft has no standard for Silverlight and an iffy standard for WPF - so this would allow you to implement your verbs as required by your UI framework.
And ViewModel can be used as a base class if you are using the commanding model provided by CSLA .NET, which may be very useful if you are implementing your own UI framework.
Hopefully this is a way to make everyone reasonably happy :)
Rocky,
Any examples using the new ViewModel<T> class yet? I was reviewing the code and it looks like you expect the Model property to be set externally - possibly through data-binding since it is defined as a DependancyProperty. This has me a bit confused since it was my expectation that we would be doing something similar to the CslaDataProvider and supporting the asynchronous loading of the model object under-the-covers of the ViewModel.
In other words, I expected to see code in the Model getter that trigger an asynchronous method call to retrieve the instance and set it to the Model property. Right now I don't see anything that resembles this.
Can you share your thoughts and intentions? (Examples always work, too!)
Creating the Model instance is something I haven’t figured
out quite yet, and so I’ve moved on to working on some other things
(PropertyStatus) while I think about it.
But this thread is a good place to solicit input.
The flaw in the data provider model is that there’s a
really steep cliff.
If your object can be retrieved/created without parameters, or
with hard-coded parameters, you can do everything in XAML.
But if your object requires variable parameters – especially
if they need to come from a previous page/form – then there’s no real
answer beyond code-behind.
One of my goals is to eliminate (or radically minimize)
code-behind, so this means the data provider approach isn’t desirable, and
this is one reason I haven’t replicated it in ViewModel<T>.
It seems to me that the ideal solution somehow involves the
ViewModel being in control of the create/retrieve operation. And that somehow
the ViewModel would have any parameters necessary to do the retrieve.
Since a very common scenario is that we got to the current form
from a previous form, this implies that the previous form’s ViewModel has
a way to pass parameters to this form’s ViewModel. In fact, it would be
really nice if the previous form’s VM could actually create this form’s
VM – or could invoke a Controller that does the creation. Something like
that.
Then bring the various navigator models into the picture –
either the SL 3 one or the CSLA one. They allow passing parameters as long as
the values can be represented by text (in a URI), and the navigator component
basically acts like a Controller.
So now you might argue that the primary model is that form A
navigates to form B and provides the necessary parameters through the
navigation URI. So now form B’s VM needs a way to get the parameters from
that URI so it can initiate the retrieve of the Model.
There’s no scenario I can see where it is desirable for
the XAML to trigger retrieval of the model.
You know, for someone who didn't want to make a UI framework, you seem to be doing a lot of "UI framework"-type things lately...
I've seen this come up a couple of different places, but I'm still confused about it. What is the driving force behind the "no code-behind" concept? Maybe I just haven't worked with WPF/Silverlight enough, but I'm still searching for a reason why code that isn't "visual candy" is such a Bad Thing. I'm not talking about putting all your code in the code-behind - but I'm trying to figure out why a "Passive View" concept has become The Way. Sure, it does make for easier testing - but since XAML (and the attendant technologies that use it) is still relatively immature, we seem to be going through an awful lot of hoops...
Ultimately, all you're doing is replacing developer's code-behind with yours. I do realize there is a difference, and I know that a fair amount of the code would probably be boilerplate anyway. But that could probably be handled through the UI framework you advocate developers build at the start of any project. This code would arguably be simpler than what you're trying to do, since it can be built specifically to solve the application/navigation model they are building. The more you do, the more complicated your code gets, because you have to try and cover the "80/20 Rule".
- Scott
I won’t argue with you Scott – I’m not
entirely sold on this MVVM thing myself.
I rather liked the data provider model, coupled with UI-oriented
bits of code in the code-behind. I thought (and think) that it is a very
effective and productive way to build the UI in XAML.
You’ll notice that I’m not dropping
CslaDataProvider, and in fact 3.8 includes a couple really nice enhancements of
the control to make it work better in master-detail scenarios. This is because
I like the data provider model quite a lot, especially as I did it in
Silverlight (WPF imposes some not-so-friendly constraints I’m not happy
with).
At the same time the buzz is all around MVVM, and so I feel that
it is very important that CSLA work with that model as well. I surely don’t
intend on writing a UI framework, but there are aspects to some controls (like
PropertyStatus) that make the MVVM approach less smooth than it could be.
Additionally, in my mind, if you create a ViewModel you are
going to want a base set of behaviors when the Model is a CSLA business object,
and so I’m creating a basic ViewModel base class (2 actually) to make it
easier for MVVM people to create their VM types. If someone doesn’t like
the base class, they can safely ignore it, but I suspect that most people will
want their VM to include the stuff in my base classes.
In the end I absolutely think you are right: the ViewModel is
just a different place to put code-behind. The only real difference I can see
that matters is that it is more testable. Whether that is worth the increased
complexity isn’t clear to me, but some people accept a lot of complexity
and cost to get testability – and as a consultant I can’t complain
if I’m on such a project because I get paid by the hour :)
Thanks Paul, that’s good input.
This is exactly why my current ViewModel base classes are very
basic and don’t impose or implement any create/fetch behaviors. By
leaving that out of the base classes, I allow you to very easily create your
own VM base class (subclass of mine presumably) that adds whatever create/fetch
model you need to integrate with your UI/navigation framework.
I’ve been doing something very similar to what you
describe – requiring a convention by which the primary ViewModel for a
form is a resource named “ViewModel”. That works for a lot of
simpler forms, but is a little problematic for more complex forms where the
form leverages multiple VM objects.
The thing is, as soon as I got to this point I realized that
every UI framework out there will come up with a different set of such
conventions. Since Microsoft hasn’t provided any standard around this, everyone
will make up their own thing – and since I don’t want CSLA to become
a UI framework, I don’t really want to make up one too – at least
not in CSLA.
Rocky
The generic issue is a pain point right now. I was hoping to find a clever solution, but so far that hasn't worked, and I expect that my next move is to change the ViewModel classes to be non-generic.
I'm not sure we lose much by doing that, but it would have been nice if Model could have been strongly typed :(
I'll give serious consideration to implementing a create/fetch model in the ViewModel class (though probably not ViewModelBase) since it is somewhat more "CSLA specific" if that makes sense.
What I'm not sure is where the value comes in in ViewModel implementing a Refresh() method.
To do MVVM you need a commanding infrastructure of some sort - beyond the WPF one, and of course there isn't one in SL.
Everyone's commanding infrastructure is different, and imposes different constraints on the verb method signatures.
This means there's no value in ViewModelBase providing any public methods at all, because we must assume they'll have the wrong signature for most UI frameworks.
I am implementing ViewModel as a subclass of ViewModelBase, and ViewModel implements a set of base verbs that work with CSLA's Invoke action and InvokeMethod property (two ways to do the same thing). Essentially ViewModel supports CSLA's commanding implementation.
But a general Refresh() method would then have to be protected, because everything in ViewModelBase is protected (all methods anyway).
And since I don't know how to get your criteria/parameters, or which factory method (if you are using factory methods) to invoke on your type to do a refresh, I can't provide any implementation at all really.
Even if I add a protected property so you can set the name of the factory method in your VMs ctor, I still don't know where to get any parameters.
And there's also the concept of a child VM - a VM that exists inside a DataTemplate, or even on the main form, but to manage some set of child or detail data. There is no concept of "refresh" on something like that, because it gets its data through binding to the parent VM.
I could go down the data provider route: have you tell me the name of the static factory and have a protected List<object> for parameters. But I am not sure this saves any code or effort on the part of someone implementing the VM.
This is why I was wondering if you had any examples using the new ViewModel class because I think that may lead to an answer.
Going along what I was thinking, I could see the ViewModel providing the "hooks" for create/fetch while leaving the implementation to the subclass. So, for instance, in the Model property getter, if the model is null, call the Refresh or GetData abstract method. Since the Model property setter is accessible, the subclass can use whatever means to retrieve or create the object then set the base class property which will raise the necessary event(s) for data-binding to update the UI.
If I'm doing an asynchronous fetch, Refresh/GetData will start the process and some handler in the subclass will be called when completed and the latter will set the Model property. Seems like the best of both worlds.
The whole process is triggered in the same manner as with the CslaDataProvider. When data-binding polls the Model property, if null... You could even include an option for InitialLoadEnabled.
I like the fact that CslaViewModel is abstract and intended for us to subclass. I found myself subclassing the ASP.NET CslaDataSource more often than not as a way to encapsulate the logic and make it easier for designers to work with the features consistently.
To the previous question about no code-behind, I just had the exact same conversation this morning. From my perspective, it really boils down to the idea that these applications are developed by two distinct roles: developers and designers. The latter are graphics/UI people who know how to make great looking interfaces but may not know - or more accurately, are not required to know - how to code. Developers on the other hand, tend to make lousy user interfaces. We put square controls in a table-like grid layout and call it done. If you think about the roles Visual Studio and Expression Blend play in the development process, you'll see that it is consistent with this thinking.
So, I think the goal is to decouple the code that developers work on from the XAML that designers work on. That's where this stems from. And, imo, I think it is a good thing because it does encapsulate code a little better and allows me to follow this approach to developing my applications. I no longer have developers waiting for designers to check in changes to the UI so they can make code changes and vice versa.
Finally, speaking from very recent experience, locking in how things are done so strictly as to define the name that must be used, etc. only makes code more unusable instead of the other way around. We tend to present these architypes as patterns, approaches and solutions that should be applied when and where they fit. They should be flexible to fit the situation, not dictate every aspect.
I worked with a brilliant developer not to long ago that had created a UI framework for the company's applications that made it a snap to generate a robust Windows Forms application quickly by subclassing types in his framework. The problem? He wasn't a student of data-binding so when a new developer (me!) tried to work with his framework using some of the latest tools and techniques, including Csla, his framework fell apart because it was way too rigid in its implementation.
Just my two cents.
SonOfPirate:To the previous question about no code-behind, I just had the exact same conversation this morning. From my perspective, it really boils down to the idea that these applications are developed by two distinct roles: developers and designers. The latter are graphics/UI people who know how to make great looking interfaces but may not know - or more accurately, are not required to know - how to code. Developers on the other hand, tend to make lousy user interfaces. We put square controls in a table-like grid layout and call it done. If you think about the roles Visual Studio and Expression Blend play in the development process, you'll see that it is consistent with this thinking.
So, I think the goal is to decouple the code that developers work on from the XAML that designers work on. That's where this stems from. And, imo, I think it is a good thing because it does encapsulate code a little better and allows me to follow this approach to developing my applications. I no longer have developers waiting for designers to check in changes to the UI so they can make code changes and vice versa.
I must be working in the wrong places, because in the years I have been programming (admittedly only about 13), I have never worked in an environment where the UI designer and coder were different people. I understand that's the model that MS is trying to go for with the whole Blend/VS thing, and that's OK. I just don't see that taking off too well in the MS world - Microsoft has not traditionally recruited the "artsy-fartsy" crowd very well. Also, it didn't take long for developers to b**** about the crappy XAML designer support in VS 2008 - something I understand MS intends to rectify with VS 2010. Realizing that MS has to support both types of development, I'm honestly not going to get much traction asking my boss to hire a "UI Experience designer" when they know that the next version of VS will fix many of my issues - presumably in a format that is not so art-designer-centric (and thus not such a steep learning curve for those of us who are "artistically challenged").
As far as the encapsulation aspect, that's certainly a good goal to have, and you certainly do raise a point about "waiting for designers". But I find the whole thing to be a lot of quibbling over what feels like semantics to me. And in the end, the whole no-code-behind MVVM seems to make your coders do more work than they might have to/should. After all, once you take the "event code" and move it one layer away from the actual event, you end up writing a certain amount of code just to transfer control around. This code is very boilerplate, and typically can't be abstracted out. Sure, you can test it. But it all ends up being more code, which means more test code...
Apparently too old-school for his own good...
- Scott
Copyright (c) Marimer LLC