Thursday, April 24, 2008

Dunn Training has been offering a very good 3 day class on CSLA .NET for some time now, with lots of great feedback. And this class continues (with a sold-out class coming up in Toronto).

As a compliment to that class, Dunn is now lining up a bigger and deeper 5 day master class. The plan is to have just two of these each year.

This master class is quite different from the 3 day class. It will have more lecture, deeper labs and a faster pace. They tell me the intent is to cover everything from OO design to CSLA object creation to WPF/Windows/Web/WCF/WF interface design to LINQ in one intense week.

Not only will this be the ultimate in CSLA .NET training, it'll be some incredibly awesome training on .NET itself!!

Thursday, April 24, 2008 2:45:39 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, April 23, 2008

I spent some time over the past few days using my prototype Silverlight serializer to build a prototype Silverlight data portal. It is still fairly far from complete, but at least I've proved out the basic concept and uncovered some interesting side-effects of living in Silverlight.

The good news is that the basic concept of the data portal works. Defining objects that physically move between the Silverlight client and a .NET web server is practical, and works in a manner similar to the pure .NET data portal.

The bad news is that it can't work exactly like the pure .NET data portal, and the technique does require some manual effort when creating the business assemblies (yes, plural).

The approach I'm taking involves having two business assemblies (VS projects) that share many of the same code files. Suppose you want to have a Person object move between the client and server. You need Person in a Silverlight class library and in a .NET class library. This means two projects are required, even if they have the same code file.

Visual Studio makes this reasonable, because you can create the file in one project (say the Silverlight class library) and then Add Existing Item and use the Link feature to get that same file included into a .NET class library project.

I also make the class be a partial class, so I can add extra code to the .NET class library implementation. The result is:

BusinessLibrary.Client (Silverlight class library)
  -> Person.cs

BusinessLibrary.Server (.NET class library)
  -> Person.cs (linked from BusinessLibrary.Client)
  -> Person.Server.cs

One key thing is that both projects build a file called BusinessLibrary.dll. Also, because Person.cs is a shared file, it obviously has the same namespace. This is all very important, because the serializer requires that the fully qualified type name ("namespace.type,assembly") be the same on client and server. In my case it is "BusinessLibrary.Person,BusinessLibrary".

The Person.Server.cs file contains the server-only parts of the Person class - it is just the rest of the partial class. The only catch here is that it can not define any fields because that would obviously confuse the serializer since those fields wouldn't exist on the client. Well, actually it could define fields as long as they were marked as NonSerialized.

Of course you could also have a partial Person.Client.cs in the Silverlight class library - though I haven't found a need for that just yet.

One thing I'm debating is whether the .NET side of the data portal should just directly delegate Silverlight calls into the "real" data portal - effectively acting as a passive router between Silverlight and the .NET objects. OR the .NET side of the data portal could invoke specific methods (like Silverlight_Create(), Silverlight_Update(), etc) so the business developer can include code to decide whether the calls should be processed on the server at all.

The first approach is simple, and certainly makes for a compelling story because it works very much like CSLA today. The Silverlight client gets/updates objects in a very direct manner.

The second approach is a little more complex, but might be better because I'm not sure you should blindly trust anything coming from the Silverlight client. You can make a good argument that Silverlight is always outside the trust boundary of your server application, so blindly passing calls from the client through the data portal may not be advisable.

Either way, what's really cool is that the original .NET data portal remains fully intact. This means that the following two physical deployment scenarios are available:

Silverlight -> Web server -> database
Silverlight -> Web server -> App server -> database

Whether the web/app server is in 2- or 3-tier configuration is just a matter of how the original .NET data portal (running on the web server) is configured. I think that's awesome, as it easily enables two very common web server configurations.

The big difference in how the Silverlight data portal works as compared to the .NET data portal is on the client. In Silverlight you should never block the main UI thread, which means calls to the server should be asynchronous. Which means the UI code can't just do this:

var person = Person.GetPerson(123);

That sort of synchronous call would block the UI thread and lock the browser. Instead, my current approach requires the UI developer to write code like this:

var dp = new Csla.DataPortal();
dp.FetchCompleted +=
  new EventHandler<Csla.DataPortalResult<Person>>(dp_FetchCompleted);
dp.BeginFetch<Person>(new SingleCriteria<int>(123));

with a dp_FetchCompleted() method like:

private void dp_FetchCompleted(object sender, Csla.DataPortalResult<Person> e)
{
  if (e.Error != null)
    // e.Error is an exception - deal with the issue
  else
    // e.Object is your result - use it
}

So the UI code is more cumbersome than in .NET, but it follows the basic service-calling technique used in any current Silverlight code, and I don't think it is too bad. It isn't clear how to make this any simpler really.

Wednesday, April 23, 2008 8:08:36 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Tuesday, April 22, 2008

Yes, I'm a comic book collector :)

FREE COMIC BOOK DAY 2008 - MAY 3RD 2008

FCBD LogoIt seems that every year FREE COMIC BOOK DAY gets bigger and bigger and it looks like this year is going to be no exception! It's a great opportunity to introduce someone new to the world of comic books! Over 2.5 million comic books will be given away this year. In addition, this year is featuring the widest variety of Free Comic Book Day Comics ever! Support your local comic book store and grab some family and friends and get some free comic books and a great time!

www.FREECOMICBOOKDAY.COM

Tuesday, April 22, 2008 1:08:03 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Monday, April 21, 2008

Shannon Braun and I were interviewed by Jeff Brand, the Twin Cities .NET Developer Evangelist for Microsoft. Jeff does a podcast titled Spaghetti Code, and we discussed our experiences at the MIX 08 conference earlier this spring.

http://www.slickthought.net/post/Spaghetti-Code-Podcast---Recapping-MIX-with-Rocky-Lhotka-and-Shannon-Braun.aspx

Monday, April 21, 2008 7:14:22 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Sunday, April 13, 2008

Silverlight 2.0 doesn't have an equivalent to the BinaryFormatter or NetDataContractSerializer. This makes some things quite challenging - in my case building CSLA Light. CSLA .NET requires high-fidelity serialization both for implementation of the Clone() operation and within the data portal.

I've been working on building a Silverlight-compatible equivalent to the BinaryFormatter/NDCS. It turns out to be quite hard due to the limitations of the Silverlight sandbox.

For example, Silverlight does have reflection, even against private fields. However, you can only get or set a private field with code inside the same class as the field declaration. You can't get/set a field from another object, or even from a base class or subclass. The reflection call must be in the same class!

At this point I have a prototype serializer that works in some limited scenarios. It is a starting point. Some aspects aren't ideal, but may just be the way they are to get around how Silverlight works. Still, the end result is relatively cool.

To use the serializer:

  1. Build the Csla project (it is a Silverlight Class Library) and reference it from your Silverlight application
  2. In your business class, add a using/Imports statement for Csla.Serialization
  3. Add the Serializable attribute to your class
  4. You class must also either inherit from MobileObject or implement the IMobileObject interface (I recommend using inheritance, as otherwise you'll have to write a lot of nasty code)
  5. You must override GetValue() and SetValue() in your class - these methods are called by the MobileFormatter so you can reflect against your private fields. See the example below to see how this works
  6. You can now use the MobileFormatter much like you would the BinaryFormatter. See the example below

The MobileFormatter is far from complete. But it can serialize/deserialize fields of an object that contain primitive types (anything that works with Convert.ChangeType()). And it handles references to other serializable objects, both single objects and lists of serializable objects (if they implement IMobileObject or inherit from MobileList<T> ).

I'm pretty sure it can't handle arrays, nor can it handle any list type other than (effectively) List<T>. I'm not sure what it will do with enums or other types - just haven't gotten that far yet.

Here's a serializable object:

using System;
using Csla.Serialization;

namespace SilverlightApplication1
{
  [Serializable]
  public class Person : MobileObject
  {
    #region Serialization

    protected override object GetValue(System.Reflection.FieldInfo field)
    {
      if (field.DeclaringType == typeof(Person))
        return field.GetValue(this);
      else
        return base.GetValue(field);
    }

    protected override void SetValue(System.Reflection.FieldInfo field, object value)
    {
      if (field.DeclaringType == typeof(Person))
        field.SetValue(this, value);
      else
        base.SetValue(field, value);
    }

    #endregion

    public string Name { get; set; }

    [NonSerialized]
    private DateTime _birthdate;
    public DateTime BirthDate
    {
      get { return _birthDate; }
      set { _birthdate = value; }
    } 
  }
}

And here's how to serialize/deserialize the object:

var p = new Person();

var formatter = new Csla.Serialization.MobileFormatter();
var buffer = new System.IO.MemoryStream();
formatter.Serialize(buffer, p);

buffer.Position = 0;
var copyOfP = (Person)formatter.Deserialize(buffer);

Though it is unfortunate that every business class must implement GetValue() and SetValue(), I think that is a relatively small price to pay to get nearly the same capability as we have in .NET with the BinaryFormatter in terms of cloning objects, and more importantly in terms of serializing them across the network with full fidelity.

Sunday, April 13, 2008 7:42:40 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Saturday, April 12, 2008

Someone on the CSLA .NET discussion forum recently asked what new .NET 3.5 features I used in CSLA .NET 3.5. The poster noted that there are a lot of new features in .NET 3.5, which is true. They also included some .NET 3.0 features as "new", though really those features have now been around for 15 months or so and were addressed in CSLA .NET 3.0. CSLA .NET 3.0 already added support for WCF, WPF and WF, so those technologies had very little impact on CSLA .NET 3.5.

My philosophy is to use new technologies only if they provide value to me and my work. In the case of CSLA .NET this is extended slightly, such that I try to make sure CSLA .NET also supports new technologies that might be of value to people who use CSLA .NET.

While .NET 3.5 has a number of new technologies at various levels (UI, data, languages), many of them required no changes to CSLA to support. I like to think this is because I'm always trying to look into the future as I work on CSLA, anticipating at least some of what is coming so I can make the transition smoother. For example, this is why CSLA .NET 2.0 introduced a provider model for the data portal - because I knew WCF was coming in a couple years and I wanted to be ready.

Since CSLA .NET already supported data binding to WPF, Windows Forms and Web Forms, there was no real work to do at the UI level for .NET 3.5. I actually removed Csla.Wpf.Validator because WPF now directly supplies that behavior, but I really didn't add anything for UI support because it is already there.

Looking forward beyond 3.5, it is possible I'll need to add support for ASP.NET MVC because that technology eschews data binding in favor of other techniques to create the view - but it is too early to know for sure what I'll do in that regard.

Since CSLA .NET has always abstracted the business object concept from the data access technique you choose, it automatically supported LINQ to SQL (and will automatically support ADO.NET EF too). No changes required to do that were required, though I did add Csla.Data.ContextManager to simplify the use of L2S data context objects (as a companion to the new Csla.Data.ConnectionManager for raw ADO.NET connections). And I enhanced Csla.Data.DataMapper to have some more powerful mapping options that may be useful in some L2S or EF scenarios.

LINQ to Objects did require some work. Technically this too was optional, but I felt it was critical, and so there is now "LINQ to CSLA" functionality provided in 3.5 (thanks to my colleague Aaron Erickson). The primary feature of this is creating a synchronized view of a BusinessListBase list when you do a non-projection query, which means you can data bind the results of a non-projection query and allow the user to add/remove items from the query result and those changes are also reflected in the original list. As a cool option, LINQ to CSLA also implements indexed queries against lists, so if you are doing many queries against the same list object you should look into this as a performance booster!

So all that's left are some of the language enhancements that exist to support LINQ. And I do use some of them - mostly type inference (which I love). But I didn't go through the entire body of existing code to use the new language features. The risk of breaking functionality that has worked for 6-7 years is way too high! I can't see where anyone would choose to take such a risk with a body of code, but especially one like CSLA that is used by thousands of people world-wide.

That means I used some of the new language features in new code, and in code I had to rework anyway. And to be honest, I use those features sparingly and where I thought they helped.

I think trying to force new technologies/concepts/patterns into code is a bad idea. If a given pattern or technology obviously saves code/time/money or has other clear benefits then I use it, but I try never to get attached to some idea such that I force it into places where it doesn't fit with my overall goals.

Saturday, April 12, 2008 3:11:52 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Friday, April 11, 2008

VS Live Orlando VS Live Orlando is coming up soon, and I'll be speaking at the event.

I'm giving a presentation on the use of OO concepts, WCF services and Silverlight working together to build compelling web applications.

And I'm giving a full-day workshop covering a broad range of .NET technologies, focused on transitioning from the .NET 2.0 world forward into the .NET 3.5 world. Not surprisingly, I use CSLA .NET as part of this workshop, though the primary focus is on making sense out of all the different technologies you might use for creating your applications.

As a track chair and speaker for VS Live, I am able to provide you with a special discount code. Register for VS Live using the code SOLHO and save $300!

Friday, April 11, 2008 8:41:10 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 
 Thursday, April 03, 2008

CSLA .NET version 3.5 for .NET 3.5 and Visual Studio 2008 is now available for download from www.lhotka.net/cslanet/download.aspx. This version of CSLA .NET includes support for LINQ and provides substantial code reduction (often around 40%) when coding your business objects.

Check out the official launch announcement on DotNetRocks!

If you are using .NET 2.0 or 3.0 with Visual Studio 2005 or 2008 then you'll want to use CSLA .NET version 3.0.4. Version 3.0.4 includes some data binding bug fixes over version 3.0.3, and it works with .NET 2.0 or .NET 3.0. It is also available from the download page.

As always, questions and comments are welcome on the forum at http://forums.lhotka.net.

Thursday, April 03, 2008 8:27:11 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |