Rockford Lhotka

 Friday, September 28, 2007

CSLA .NET version 3.0 adds support for Microsoft .NET 3.0 features. This ~120 page ebook covers how to use these new capabilities:

  • Windows Presentation Foundation (WPF)
    • Creating WPF forms using business objects
    • Using the new controls in the Csla.Wpf namespace
      • CslaDataProvider
      • Validator
      • Authorizer
      • ObjectStatus
      • IdentityConverter
    • Maximizing XAML and minimizing C#/VB code
  • Windows Communication Foundation (WCF)
    • Using the new WCF data portal channel to seamlessly upgrade from Remoting, Web services or Enterprise Services
    • Building WCF services using business objects
    • Applying WCF security to encrypt data on the wire
    • Sending username/password credentials to a WCF service
      • Including use of the new Csla.Security.PrincipalCache class
    • Using the DataContract attribute instead of the Serializable attribute
  • Windows Workflow Foundation (WF)
    • Creating activities using business objects
    • Invoking a workflow from a business object
    • Using the WorkflowManager class in the Csla.Workflow namespace

Version 3.0 is an additive update, meaning that you only need to use the .NET 3.0 features if you are using .NET 3.0. CSLA .NET 3.0 is useful for people using .NET 2.0!! These features include:

  • Enhancements to the validation subsystem
    • Friendly names for properties
    • Better null handling in the RegExMatch rule method
    • New StringMinLength rule method
    • Help for code generation through the DecoratedRuleArgs class
  • Data binding issues
    • Fixed numerous bugs in BusinessListBase to improve data binding behavior
    • Throw exception when edit levels get out of sync, making debugging easier
    • N-level undo changed to provide parity with Windows Forms data binding requirements
  • AutoCloneOnUpdate
    • Automatically clone objects when Save() is called, but only when data portal is local
  • Enhancements to the authorization subsystem
    • CanExecuteMethod() allows authorization for arbitrary methods

CSLA .NET 3.0 includes numerous bug fixes and some feature enhancements that benefit everyone. If you are using version 2.0 or 2.1, you should consider upgrading to 3.0 to gain these benefits, even if you aren't using .NET 3.0.

See the change logs for version 3.0, version 3.0.1 and version 3.0.2 for a more detailed list of changes.

Using CSLA .NET 3.0 is completely focused on how to use the new features in version 3.0. The book does not detail the internal changes to CSLA .NET itself, so all ~120 pages help you use the enhancements added since version 2.1.

Get the book at store.lhotka.net.
(C# available now, VB available in early October)

Download the 3.0.2 code from the CSLA .NET download page.

Books | CSLA .NET | WCF | Workflow | WPF
Friday, September 28, 2007 3:21:26 PM (Central Standard Time, UTC-06:00)  #    Disclaimer

It is a reasonably well-known fact that WPF misuses the Equals() method in the data binding implementation.

If you set a DataContext to an object, then set it to another object that is logically equal to the first, but which has different data, WFP gladly ignores the new object's data:

form.DataContext = A;
B = A.Clone();
B.Value = "new value";
form.DataContext = B;

Assuming A and B retain logical equality even though Value has changed, this code results in the UI not showing the new value. Apparently the reasoning is that if the objects are equal, then there's no need to update any data through data binding.

Of course this totally confuses ReferenceEquals() with Equals(), and the result is that objects used by WFP can no longer have logical equality. They can only have reference equality.

(or, arguably, WPF forces 100% property-level equality across objects, so equality can extend to two different instances as long as they have absolutely no different property values - which seems entirely useless)

In .NET 3.0 I had a solution, at least in CslaDataProvider. The solution was to temporarily set the DataContext to null, then to the new object. The result was that the faulty (imo anyway) equality comparison was defeated.

Unfortunately, it appears that .NET 3.5 may have "fixed a bug" that prevents this from working. The result is that it appears there is NO WAY TO REFRESH DATA when fields of an object change, but the object's logical identity remains the same.

I'm not yet sure of a final solution. The current situation is very bad, because you can either use WPF or you can have logical equality between objects - but not both.

It might be the case that people who need logical equality will have to implement their own parallel Equals() concept - ignoring the standard one built into .NET. That's a really poor solution, but if Microsoft isn't going to use their own framework responsibly then we're kind of stuck. Of course operators become an issue then, since operator overloading is related to Equals() as well. I suppose you could break that relationship, but then you'd get really odd stuff like this:

x = y is true

x.Equals(y) is false

But if WPF forces Equals() to be ReferenceEquals() instead of actual equality, then we come back to being stuck.

I love WPF - it is really cool. But this particular issue is a real problem. Apparently one without a real solution.

WPF
Friday, September 28, 2007 9:02:38 AM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Saturday, September 22, 2007

I recently received this email, and wanted to share my reply.

Rocky,

Our company is going through a transformation in the way we do software.  We’re a very large company with offices all over the world, and it’s only my location that is using CSLA at this point.  We’ll now we’re faced with defending our decisions to use CSLA as the rest of the company attempts to create a “toolbox” of approved methodologies for development.  Normally I would think this is a good idea, but it seems to me that the people providing the recommendations, who interviewed us, don’t seem to have things right, especially when it comes to CSLA.

Now, I figure I can create my arguments just fine… however, I think your help would be very valuable.  Here is a list of comments made about CSLA that I feel I have to clarify or defend.  Personally, I know they are blatantly wrong, but nevertheless, they seem to be common misconceptions about CSLA.  What do you think?  Again, these are not my comments, just misconceptions that I’m hearing from the rest of the company that I need to clear up.  Also, one of the key misconceptions here is that we should use Enterprise Library as a replacement for CSLA, again, they don’t understand what CSLA  .NET is for

Misconceptions:

1. CSLA .NET is an older concept, ported to .Net, unlike Enterprise Library which was written for .Net.

2. Many CSLA features can be accomplished with Enterprise Library.

3. CSLA .NET is a “niche” framework, when compared to the widely accepted Enterprise Library.

4. CSLA .NET was not built with new technologies like WPF or WCF in mind.

5. CSLA .NET is component based and wasn’t designed to take advantage/or be compatible with SOA.

6. CSLA .NET, tied to its legacy, looks at the future of .NET and the adoption of SOA as merely an afterthought.

Those are the key misconceptions that I feel I have to address… any help you can provide in formulating my arguments would be greatly appreciated.

Thanks!

Jimbo

My reply follows:

Jimbo,

1. CSLA .NET is an older concept, ported to .Net, unlike Enterprise Library which was written for .Net.

That is not strictly true. There is a strong and complete break between the COM-based CSLA and CSLA .NET. No code carried forward, and realistically the concepts in CSLA .NET were enabled by .NET itself, and have little to do with the limited world of COM.

It is true that CSLA uses some OO concepts that have been around for a long time. These concepts have stood the test of time, and have proven to be very valuable for designing and building software. It would be foolish to discard great ideas just because they've had time to age. That'd be like discarding the wheel because it is an older concept...

It is also important to recognize that CSLA .NET and Enterprise Library are entirely complementary. CSLA .NET solves a set of problems not addressed by EntLib, and EntLib solves a set of problems not addressed by CSLA .NET.

2. Many CSLA features can be accomplished with Enterprise Library.

Again, EntLib is complimentary to CSLA .NET. Things like logging, caching, data access, configuration and logging are outside the scope of CSLA .NET.

Things like validation, authorization, data binding support and location transparency for n-tier development are the focus of CSLA .NET.

While EntLib does have a validation module, it is architecturally unsound, putting the business logic into the UI layer rather than encapsulating it in a separate business layer.

3. CSLA .NET is a “niche” framework, when compared to the widely accepted Enterprise Library.

There is no doubt that using a niche framework is a risk. And any organization using CSLA .NET must be aware of the nature of the framework in that regard.

However, it is also important to realize that CSLA .NET is the most widely used framework of its kind in .NET. Yes, EntLib is more widely used, but it does not duplicate or replace what CSLA .NET provides.

If you don’t use CSLA .NET, you still need to solve the problems it addresses. Like it or not, there are gaps in .NET around data binding, validation, authorization and so forth. Gaps that CSLA .NET solves. As do other products like NetTiers, LLBLGen, Ideablade and others. Some commercial, some not.

But none have the broad user base of CSLA .NET at this point in time.

I’ve had several people approach me at conferences to point out that they replicated CSLA .NET. They’d read my book, didn’t want to use a “niche framework” and set out to do their own thing. Months later they looked at their app and realized that they’d re-solved all those same problems. Addressed all those same gaps. And that they’d largely recreated CSLA .NET. Usually they are sad about this, realizing just how much time they wasted recreating a framework that already exists.

4. CSLA .NET was not built with new technologies like WPF or WCF in mind.

This is patently untrue. Sorry, but CSLA .NET 2.0 was written specifically with WCF and WPF in mind. I am on steering groups within Microsoft, and so help shape the nature of many of these developer-oriented products. I knew years ahead of time the basic shape and nature of .NET 3.0, and so in 2005 CSLA .NET was already prepared for these new technologies.

While most of the other bullets in the assessment are reasonable and well-considered (though I clearly dispute some conclusions), this bullet is simply absurd and discounts the many hundreds of hours of work I’ve put in over the past four or so years ensuring that CSLA .NET provides a seamless and transparent upgrade path from Windows Forms and Web Forms to WPF, and from Web services or Remoting to WCF.

I challenge you to find another framework that will allow a switch from Web services or Remoting to WCF through a simple configuration file change. And yet I accomplished this in CSLA .NET by preparing for these technologies way back in 2004 and 2005.

5. CSLA .NET is component based and wasn’t designed to take advantage/or be compatible with SOA.

There are two aspects here.

First, CSLA is a brand. Whether “component-based scalable logical architecture” is still accurately descriptive (it isn’t) doesn’t even matter anymore, because the brand is what it is. In other words, don’t read too much into the name – I’m stuck with it.

Second, there is no doubt that CSLA is designed to support n-tier client/server architectures. Such architectures are currently the best way to build interactive applications with WPF, Windows Forms and Web Forms interfaces. Like it or not, SOA simply has too much overhead and is too high-cost to be effective for most interactive application development.

It would be foolish to consider that object-oriented design is dead in the face of SOA. Or workflow. In fact, they are highly complimentary.

A service or a workflow activity are, by definition, both atomic units of functionality. If they aren’t, then you are doing them wrong.

Effectively every service and every activity are “mini-applications”. They are also effectively a use case, from an OOD perspective.

Thus you can (and often should) design and implement your services and activities using OO concepts. And CSLA .NET is all about making it easier to apply OOD/P when building applications.

As a result, whether you are building applications that consume services or that provide services or activities, CSLA .NET is a great help.

6. CSLA .NET, tied to its legacy, looks at the future of .NET and the adoption of SOA as merely an afterthought.

The reality is that CSLA .NET has been able to largely shield its users from the rapidly increasing rate of change and chaos in the Microsoft platform space. By enforcing a clear delineation between UI and business code, and by supporting .NET standard interfaces for data binding and other .NET features, CSLA .NET continues to act as a valuable buffer, allowing valuable business logic to easily move forward through time, even as interface technologies change and change and change.

More time is spent on “future-proofing” both CSLA .NET, and more importantly the users of CSLA .NET, from changes to Microsoft’s platform than any other feature of the framework. Clearly it is impossible to abstract all the changes Microsoft comes up with, but CSLA .NET strives to protect that which is most important and costly to build and maintain: your business rules and logic.

Saturday, September 22, 2007 1:36:43 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Friday, September 21, 2007

I just got back from VS Live NY - which was a great show. It sold out, and the people attending were very engaged and fun to be with. I love crowds like that!

In my all-day workshop on building distributed apps using objects I showed how to use WPF commanding to automatically enable/disable Save and Cancel buttons on a form by connecting them to a CslaDataProvider control. That's a really cool feature of WPF that I am leveraging with some of the new CSLA .NET 3.0 features.

An attendee asked if it was possible to hide the Save button, not just disable it. I hadn't thought about that, and came up with some answer involving code.

Josh Smith, who was also in the audience, has given this even further thought and sent me an email with a better, pure XAML, solution. Thank you Josh!! Here's the relevant bit of the email:

During the presentation a fellow asked you how, in WPF, to hide a Button when it is disabled.  The Button was disabled because its associated command could not execute, and he wanted to hide the Button instead of letting it sit in the UI disabled.

The solution you gave him involved some code, which threw a red flag in my mind.  IMO, this is the kind of thing you should use XAML to express, so that there are less "moving parts" in your app.  Here's one way to implement that functionality with no code at all:

<Button Command="Open" Content="_Open">
  <Button.Style>
    <Style TargetType="Button">
      <Style.Triggers>
        <Trigger Property="IsEnabled" Value="False">
          <Setter Property="Visibility" Value="Collapsed" />
        </Trigger>
      </Style.Triggers>
    </Style>
  </Button.Style>
</Button>

Depending on your layout, you might want to set Visibility to Hidden instead.

Friday, September 21, 2007 7:01:20 AM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Thursday, September 13, 2007

Every now and then I plug Magenic on my blog. This is because Magenic is a great consulting company, and I really feel good about encouraging people to come work here!

(Please note, I'm just another employee. People often think I own Magenic, but that's not true - I'm just lucky enough to work here :) )

Magenic has offices in Chicago, Atlanta, Boston, San Francisco and Minneapolis, and all the offices really need good .NET developers, Sharepoint experts, Biztalk experts and Business Intelligence/SQL people.

What is spurring this particular post, is that our Chicago office has a particular need for a BI expert :)

But if you are a .NET developer - Windows, Web, VB, C# - please consider applying for a job at Magenic.

And if you are a Sharepoint or Biztalk expert, lucky you! Those technologies are hot (especially Sharepoint/MOSS), and we'd love to talk to you!

Finally, all our offices need BI expertise, not just Chicago.

If you want to work with some of the smartest and most dedicated people in the industry, you owe it to yourself to have a talk with one of our recruiters.

Thursday, September 13, 2007 4:33:59 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Tuesday, August 28, 2007

Here's a link to a preliminary list of sessions for the upcoming Twin Cities code camp. Jason needs a few more speakers to fill out the schedule though, so if you are in the Twin Cities area and would like to present on any developer related topic (business, non-business, Microsoft, non-Microsoft - it doesn't matter!) you can find contact information here.

Tuesday, August 28, 2007 7:04:29 AM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Friday, August 24, 2007

Thanks to my friend Billy Hollis, I appear to have found the radio station I've been looking for: Pandora.

This is an online streaming service with a brain. You tell it some of your favorite artists and/or songs and it assembles a radio station that plays music similar to (and including) your selections. It calls the artists and songs you pick "seeds", and apparently uses some sort of genome-based algorithm to find that similar music.

I've been listening for nearly an hour now, based on my seeds (Rush, Queensryche, Godsmack and Disturbed) and it absolutely rocks!

The only glitch I've found is that if you open it in two browsers, it plays both songs over the top of each other. But that's more a user error than their issue I think :)

Not since CyberRadio 2000 got squashed by RIAA have I found quite the service I was looking for. I had hoped zune.net would do something like this, but Pandora beat them to it.

Friday, August 24, 2007 3:57:25 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Thursday, August 23, 2007

Magenic is providing a series of free online seminars on various IT related topics. The next one is on the value of portals.

Suppose your organization’s existing IT investments could be put to use to make your customer and partner interactions more effective and increase your company’s profits. External Portals are browser-based applications that can enable your business processes to better meet the needs of your customers, your partners and your firm.

In this power-packed agenda, the IT experts from Magenic will  introduce you to the current market trends influencing IT decisions and how External Portals can help you:

  • Generate value by creating and fostering customer intimacy.
  • Maximize customer and partner interactions with a personalized online experience.
  • Increase brand satisfaction by creating unexpected opportunities to serve customers.
  • Better understand your prospects and customers.
  • Provide visibility across your extended value chain.
  • Lower cost and improve overall quality, efficiency and profitability.
  • The extraordinary value to be gained through timely, relevant information exchange
  • The simple steps you can take today to get started.

Click here for full information about the seminar.

Thursday, August 23, 2007 7:12:20 PM (Central Standard Time, UTC-06:00)  #    Disclaimer

I am working on my Using CSLA .NET 3.0 ebook and wrote some content that I don't think I'm going to use in the book now. But I don't want to waste the effort, so I'm posting it here.

The text discusses an answer to a common question: how do I get my read-only list of X to know that some X data has been changed. Obviously the following technique can't detect that some other user has changed some data, but at least it detects and handles the case where the current user changes some data that would impact an existing read-only list in that same process.

 

Another common example occurs when there is a read-only list that should be updated when an associated editable object is saved. For instance, you might have a CustomerList object that should be updated any time a Customer is saved.

To solve that issue, the CustomerList object needs to subscribe to an event that is raised any time a Customer is saved. Such an event should be a static event on the Customer class:

  public class Customer : BusinessBase<Customer>

  {

    public static event EventHandler<Csla.Core.SavedEventArgs> CustomerSaved;

 

    protected static virtual void OnCustomerSaved(Customer sender, Csla.Core.SavedEventArgs e)

    {

      if (CustomerSaved != null)

        CustomerSaved(sender, e);

    }

 

    // ...

 

    protected override Customer Save()

    {

      Customer result = base.Save();

      OnCustomerSaved(this, new Csla.Core.SavedEventArgs(result));

      return result;

    }

  }

The CustomerSaved event is declared using the standard EventHandler<T> model, where the argument parameter is of type Csla.Core.SavedEventArgs. The reason for the use of this type is that it includes a reference to the new object instance created as a result of the Save() call.

Then the Save() method is overridden so the CustomerSaved event can be raised after the call to base.Save().

The CustomerList class can then handle this static event to be notified as any Customer object is saved:

  public class CustomerList : ReadOnlyListBase<CustomerList, CustomerInfo>

  {

    private CustomerList()

    {

      Customer.CustomerSaved += new EventHandler<Csla.Core.SavedEventArgs>(Customer_Saved);

    }

 

    private void Customer_Saved(object sender, Csla.Core.SavedEventArgs e)

    {

      // find item corresponding to sender

      // and update item with e.NewObject

      Customer old = (Customer)sender;

      if (old.IsNew)

      {

        // it is a new item

        IsReadOnly = false;

        Add(CustomerInfo.LoadInfo((Customer)e.NewObject));

        IsReadOnly = true;

      }

      else

      {

        // it is an existing item

        foreach (CustomerInfo child in this)

          if (child.Id == old.Id)

          {

            child.UpdateValues((Customer)e.NewObject);

            break;

          }

      }

    }

  }

The final requirement is that the read-only CustomerInfo business object implement a LoadInfo() factory method, and an UpdateValues() method.

The LoadInfo() factory method is used to initialize a new instance of the read-only object with the data from the new Customer object. Loading the data from the Customer object avoids having to reload the data from the database when it is already available in memory:

  internal static CustomerInfo LoadInfo(Customer cust)

  {

    CustomerInfo info = new CustomerInfo();

    info.UpdateValues(cust);

    return info;

  }

The UpdateValues() method sets the read-only object’s fields based on the values from the Customer object:

  internal void UpdateValues(Customer cust)

  {

    _id = cust.Id;

    _name = cust.Name;

    // and so on ...

  }

The end result is that the CustomerList object is updated to reflect changes to the saved Customer object. The CustomerSaved event notifies CustomerList of the change, and (in most cases) CustomerInfo can update itself without hitting the database by loading the data from the Customer object that is already in memory.

Thursday, August 23, 2007 3:35:30 PM (Central Standard Time, UTC-06:00)  #    Disclaimer
 Thursday, August 9, 2007

I just spent the past few days pulling my hair out trying to get a custom principal to work in WCF.

Google returned all sorts of interesting, but often outdated and/or overly complex results. I kept looking at the techniques people were using, thinking this can't be so hard!!!

Well, it turns out that it isn't that hard, but it is terribly obscure... Fortunately I was able to get help from various people, including Clemens Vasters, Juval Lowy and (in this case most importantly) Christian Weyer. Even these noted WCF experts provided an array of options rather than a unified, simple answer like I'd expected.

My conclusion: while WCF really is cool as can be, it is also a deep plumbing technology that begs for abstraction for use by "normal" people.

Anyway, as a result of my queries, Christian got one of his colleagues to write the blog post I wish I had found a few days ago: www.leastprivilege.com - Custom Principals and WCF.

One of my motivations in researching this issue was for the WCF chapter in my upcoming Using CSLA .NET 3.0 ebook. There's now a comprehensive discussion of the topic in that chapter, starting with the creation and use of X.509 certificates and walking through the whole process of implementing custom authentication and using a custom principal in a WCF service. Dominick's blog post is great, but only covers about a third of the overall solution in the end.

The ebook should be out toward the end of September, for those who are wondering.

Thursday, August 9, 2007 2:28:24 PM (Central Standard Time, UTC-06:00)  #    Disclaimer