Thursday, February 28, 2008

One of my primary goals with CSLA .NET 3.5 was to reduce the amount of code necessary for common business object tasks - like declaring a property or implementing a parent-child relationship. I've mentioned what I'm doing on the forum and elsewhere, but I thought a summary blog post would be nice. I'm motivated, because I spent some time earlier today upgrading some business object code based on CSLA 3.0.3 to 3.5 and it was just fun to watch the class shrink :)

Basic Properties

Prior to 3.5 my properties were comparatively large:

public string Name
{
  [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
  get
  {
    CanReadProperty(true);
    return _name;
  }
  [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
  set
  {
    CanWriteProperty(true);
    if (value == null) value = string.Empty;
    if (_name != value)
    {
      _name = value;
      PropertyHasChanged();
    }
  }
}

Now the same property looks like this:

private static PropertyInfo<string> NameProperty =
  RegisterProperty<string>(typeof(CertificationEdit), new PropertyInfo<string>("Name"));
public string Name
{
  get { return GetProperty<string>(NameProperty); }
  set { SetProperty<string>(NameProperty, value); }
}

I think that is so cool!! Though there's a performance hit to this much reduction, because you'll notice there's no backing field. In this case CSLA is actually managing the property value in the background and that incurs a little overhead. You can compromise if you'd like:

private static PropertyInfo<string> NameProperty =
  RegisterProperty<string>(typeof(CertificationEdit), new PropertyInfo<string>("Name"));
private string _name = NameProperty.DefaultValue;
public string Name
{
  get { return GetProperty<string>(NameProperty, _name); }
  set { SetProperty<string>(NameProperty, ref _name, value); }
}

Nearly the same code, but now with a private backing field so CSLA doesn't have to manage the value. Slightly faster, with slightly more code.

Either way, all the authorization, validation and data binding support works just like it did with the old syntax, so all the core features of CSLA .NET just keep working in your favor - with less code to write and maintain.

Child Object Properties

This new syntax works for child objects as well. A child used to look like this:

private ChildType _child;
public ChildType Child
{
  [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
  get
  {
    CanReadProperty(true);
    return _child;
  }
}

The new syntax requires that CSLA manage the property value for child objects:

private static PropertyInfo<ChildType> ChildProperty =
  RegisterProperty<ChildType>(typeof(CertificationEdit), new PropertyInfo<string>("Child"));
public ChildType Child
{
  get { return GetProperty<ChildType>(ChildProperty); }
}

The really cool part isn't the minor code savings in the property - it is the code savings elsewhere. Prior to 3.5 a parent object had to override IsDirty and IsValid, and had to hook and re-hook child data binding events. None of that code is required now! Because CSLA is managing the child object value, it can entirely handle IsDirty, IsValid and all data binding events automatically. This saves a lot of code in every parent object.

Even better, this eliminates code that a lot of people forgot to write, or forgot to update when adding a new child. In short, this eliminates a primary source of bugs/pain when dealing with parent-child object relationships.

There are other areas in 3.5 where I've reduced the code required, and I'll blog about others (like reducing data access code, eliminating many criteria classes and more) in future posts.

Thursday, February 28, 2008 9:25:11 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, February 27, 2008

I'm psyched! I finally figured out how to get the Csla.Wpf.CslaDataProvider control to support a Delete command that removes child items from a databound list object.

As you might expect, the answer to the problem was staring me in the face the whole time - I just didn't see it. Isn't that the way things often work? ;)

Since day one, CslaDataProvider has support the Save, Undo and AddNew commands (using XAML commanding), so it has been possible to create Save, Cancel and Add buttons on a form purely through XAML - no code-behind required at all.

Now, with this new change it is also possible to implement a Remove button in a DataTemplate with no code-behind. The button can use the standard Delete command to tell the CslaDataProvider managing the BusinessListBase object to remove the child object bound to that row in the DataTemplate. The XAML looks like this:

<DataTemplate x:Key="lbTemplate">
  <Grid>
    <StackPanel Orientation="Horizontal">
      <TextBlock>Id:</TextBlock>
      <TextBox Text="{Binding Path=Id, Converter={StaticResource IdentityConverter}, ValidatesOnDataErrors=True}" Width="100" />
      <TextBlock>Name:</TextBlock>
      <TextBox Text="{Binding Path=Name, Converter={StaticResource IdentityConverter}, ValidatesOnDataErrors=True}" Width="250" />
      <Button
        Command="ApplicationCommands.Delete"
        CommandParameter="{Binding}"
        CommandTarget="{Binding Source={StaticResource RoleList}, Path=CommandManager, BindsDirectlyToSource=True}"
        HorizontalAlignment="Left">Remove</Button>
    </StackPanel>
  </Grid>
</DataTemplate>

The key was realizing that the CommandParameter could be bound to the entire object that is represented by this DataTemplate - the individual row object. This revelation meant that the CslaDataProvider control can in fact remove that item because an equality comparison is possible. So ApplicationCommands.Delete passes the child object reference to the data provider, which removes the item from the databound list object and that's it!

So this means you can now create a typical maintenance screen with no code behind the XAML. None. You have to write zero lines of VB/C#. Too cool!!

And it means that even on a more complex screen you still don't need to write save/cancel/add new/remove code. That's a lot of code savings! Often all you need to write is code dealing with navigation from this screen to some other screen, perhaps some exception handling code (which I put in a base class) and some authorization code to provide visual cues to the user about what they can and can't do.

Is this really the final step? I doubt it. I already have some ideas on how to expose the authorization knowledge encapsulated by the business object such that it can be directly used within the XAML. I don't know if I'll get that working, but if I can reduce/elminate the UI authorization code (that provides visual cues to the user) and get that into XAML then even more forms will become codeless.

Wednesday, February 27, 2008 8:41:14 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 

Yesterday I co-presented (with Anthony Handley, one of Magenic's lead designers), giving a talk on building applications using XAML (WPF and Silverlight). It is a fun talk, because we spend the entire time walking through the process and code and design assets we used/created to build an application. And we discuss the great and not-so-great parts of using Visual Studio, Expression Blend, Expression Design, TFS and various other tools in such a collaborative project.

But I did something bad. Something I really know not to do, but sometimes you just get carried away I guess. My mistake? I tweaked some code right before going on stage. I should really know better...

So part way into our talk the code refuses to build. (in retrospect I know exactly what I did, I got two parameters backward on a method) Debugging on stage is never fun, and we surely didn't have time for it in this talk!

Fortunately for us, Magenic provides all consultants with high speed cell modem service for our laptops. This meant we were connected at DSL speed to the Internet, and Anthony was able to quickly use TFS to undo pending changes to the file I'd tweaked. Which goes to show two things. First, good source control is invaluable. Second, Magenic's belief that our consultants should have ubiquitous Internet access really pays off!!

What could have been a demo disaster, turned instead into illustration of the ease with which you can use TFS from within Visual Studio 2008 :)

(p.s. For those living in the Twin Cities area, Anthony and I will be giving a (free, I think) 3 hour version of this talk on April 24 at the Microsoft office in Minneapolis. I'm looking forward to that, because we have to gloss over so much stuff to fit the talk into 60-75 minutes, and it will be great to dig deeper into each sub-topic over a 3 hour period. Watch www.magenic.com for details on registration as the date gets closer.)

Wednesday, February 27, 2008 8:18:49 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, February 25, 2008

SFVS Live 2008 kicks off in San Francisco on March 30.

I'll be speaking there, giving a talk on merging SOA and OO concepts with a Silverlight 2.0 UI - fun stuff!! :)

And I'll be giving a full-day workshop, showing how to appropriately leverage the broad set of .NET technologies to build applications. There are so many ways to solve the same problem in .NET, whether that be user interaction, getting your data, building a business layer or anything else. Microsoft seems determined to provide 2 to infinity ways to do any given thing, and it seems like chaos. My goal is to provide some sense of order, or at least an architectural model, around the chaos to make it easier to leverage the power of the technologies.

I'm also co-chair of the Core .NET track, and I'm excited about many of the speaker and topic selections for the conference. With so much going on around .NET development, this is a great time to be involved with one of the leading developer conferences in the world!

As a track chair and speaker, I have a discount code you can use to register to get 25% off the registration for a Gold Passport. Just go here to register and use code SPLHO.

See you in San Francisco!

Monday, February 25, 2008 8:45:06 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Friday, February 22, 2008

CSLA .NET version 3.5 is for Visual Studio 2008 and .NET 3.5 only.

If you are using .NET 3.0 or .NET 2.0 then CSLA .NET version 3.0.x is for you. Version 3.0.4 is a maintenance release incorporating some important bug fixes, especially around data binding.

Version 3.0.4 will release concurrently with version 3.5, and I have put a refresh of the 3.0.4 code online for download at www.lhotka.net/cslanet/download.aspx.

This release is quite stable, and you should consider using it if the bug fixes apply to you. See the change log for details.

Friday, February 22, 2008 10:20:15 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 

CSLA .NET version 3.5 Beta 2 is now available for download from www.lhotka.net/cslanet/download.aspx.

Please read the change log prior to installing/using this release. If you are coming from version 3.0 or lower there are a few potential breaking changes. If you are coming from 3.5 Beta 1 there is one potential breaking change.

There are numerous bug fixes and feature tweaks from Beta 1 to Beta 2. These are thanks to the great feedback and help I've recieved from numerous people on the CSLA forum (http://forums.lhotka.net/) - thank you all for your help!!!

I am excited to release Beta 2, because we're narrowing in on a final release of version 3.5 and any changes now will be bug fixes or stabilization. Any testing you can do on this new release is appreciated and will help ensure high quality in the final release.

Friday, February 22, 2008 10:06:52 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |