Wednesday, August 01, 2007

I wrote the following for the Using CSLA .NET 3.0 ebook, but I don't think I'm going to use it now, because I've wrapped most of this into a new class in CSLA .NET. Rather than letting this go to waste though, I thought I'd post it here. Remember that it is just draft content, so it may have typos or errors, but perhaps it will be useful to someone:

Basic Workflow Execution

Executing a workflow is a little tricky, because workflows default to running on a background thread. That means you must take steps to ensure that the workflow completes before the host process terminates.

One way to solve this issue is to always execute a workflow synchronously. Another is to use a thread synchronization object to prevent the process from terminating until the workflow completes.

Note: It is also possible to suspend and resume workflows, and even to unload them from memory so they store their state in a database. Later you can reload that workflow instance and resume it. These advanced scenarios are outside the scope of this book

Synchronous Execution

The code to synchronously execute a workflow follows a standard pattern:

1.      Create an instance of the WorkflowRuntime.

2.      Create a synchronization object.

3.      Set up event handlers.

4.      Create workflow instance.

5.      Ensure you have a valid principal object.

6.      Start the workflow.

7.      Wait for the workflow to complete.

The only step unique to CSLA .NET is number 5, and that is only required if you are using custom authentication. The WF runtime will automatically ensure that the background thread that executes the workflow has the same principal as the thread that calls the workflow’s Start() method, but you must ensure that the principal is set on the current thread before calling Start().

The following code implements these steps to execute the ProjectWorkflow implemented earlier in this chapter:

      using (WorkflowRuntime workflowRuntime = new WorkflowRuntime())

      {

        Exeception error = null;

 

        AutoResetEvent waitHandle = new AutoResetEvent(false);

        workflowRuntime.WorkflowCompleted +=

          delegate(object sender, WorkflowCompletedEventArgs e)

          {

             waitHandle.Set();

          };

        workflowRuntime.WorkflowTerminated +=

          delegate(object sender, WorkflowTerminatedEventArgs e)

          {

            error = e.Exception;

            waitHandle.Set();

          };

 

        // create workflow instance

        Dictionary<string,object> parameters = new Dictionary<string,object>();

        parameters.Add("ProjectId", projectId);

        WorkflowInstance instance =

          workflowRuntime.CreateWorkflow(

            typeof(PTWorkflow.ProjectWorkflow),

            parameters);

 

        // login before starting WF instance

        ProjectTracker.Library.Security.PTPrincipal.Login("pm", "pm");

 

        // execute workflow

        instance.Start();

 

        // wait for workflow to complete

        waitHandle.WaitOne();

 

        // throw any workflow exception

        if (error != null)

          throw error;

      }

Creating the workflow instance involves setting up a Dictionary<string, object> that contains name/value pairs for any parameters to be passed into th workflow instance:

        // create workflow instance

        Dictionary<string,object> parameters = new Dictionary<string,object>();

        parameters.Add("ProjectId", projectId);

        WorkflowInstance instance =

          workflowRuntime.CreateWorkflow(

            typeof(PTWorkflow.ProjectWorkflow),

            parameters);

The name in the dictionary must correspond to the name of a dependency property defined by the workflow, and of course the type of the value must match the dependency property type.

Keep in mind that creating an instance of a workflow does not start the workflow. The workflow won’t start executing until the Start() method is called later in the code.

The waitHandle synchronization object is the key to making this process synchronous. The waitHandle object starts out unset because false is passed to its constructor as its initial state:

        AutoResetEvent waitHandle = new AutoResetEvent(false);

At the bottom of the code is a line that calls WaitOne(), thus blocking the current thread until waitHandle is set:

        // execute workflow

        instance.Start();

 

        // wait for workflow to complete

        waitHandle.WaitOne();

While the current (starting) thread is blocked, the workflow is busy executing on a background thread. In other words, the Start() call returns immediately, having just started the workflow instance executing on a background thread. Without the WaitOne() call, the current thread would exit the code block, which would dispose the WF engine instance while it is executing the workflow. The result would be an exception.

Notice how the event handlers for the WorkflowCompleted and WorkflowTerminated events both call waitHandle.Set(). These events are raised by the WF engine when the workflow either completes or terminates unexpectedly. Either way, by calling the Set() method, the current thread is released so it can continue running.

In the case of a workflow terminating unexpectedly, the exception from the workflow is made available to the WorkflowTerminated event handler. You can choose what to do with this information as appropriate for your application. One technique is shown here, which is to store the Exception object in a field:

          delegate(object sender, WorkflowTerminatedEventArgs e)

          {

            error = e.Exception;

            waitHandle.Set();

          };

And then have the current thread throw the exception once it is unblocked:

        // wait for workflow to complete

        waitHandle.WaitOne();

 

        // throw any workflow exception

        if (error != null)

          throw error;

The result of this code is that the workflow appears to run synchronously, even though it really executes on a background thread.

Asynchronous Execution

Allowing a workflow to run asynchronously is just a slightly more complex version of running the workflow synchronously. The important thing is to ensure that your process doesn’t exit until the workflow is complete. This means that the synchronization object must be available at a broader scope so you can write code to prevent the application from closing if the workflow is still running.

You also must come up with a way to deal with any exception object in the case that the workflow terminates unexpectedly. One solution is to elevate the error field from the previous example to a broader scope as well.

Finally, the WorkflowRuntime instance must remain in memory until the workflow completes.

This means that you must define these fields so they exist at an application level, for instance using static fields:

  private static AutoResetEvent _waitHandle = null;

  private static Exception _workflowError = null;

  private static WorkflowRuntime _workflowRuntime = null;

Then you can create a method to start the workflow:

    public static void BeginWorkflow(Guid projectId)

    {

      _workflowRuntime = new WorkflowRuntime();

      _waitHandle = new AutoResetEvent(false);

      _workflowRuntime.WorkflowCompleted +=

        delegate(object sender, WorkflowCompletedEventArgs e)

        {

           _waitHandle.Set();

        };

      _workflowRuntime.WorkflowTerminated +=

        delegate(object sender, WorkflowTerminatedEventArgs e)

        {

          _workflowError = e.Exception;

          _waitHandle.Set();

        };

 

      // create workflow instance

      Dictionary<string,object> parameters = new Dictionary<string,object>();

      parameters.Add("ProjectId", projectId);

      WorkflowInstance instance =

        _workflowRuntime.CreateWorkflow(

          typeof(PTWorkflow.ProjectWorkflow),

          parameters);

 

      // login before starting WF instance

      ProjectTracker.Library.Security.PTPrincipal.Login("pm", "pm");

 

      // execute workflow

      instance.Start();

    }

Notice that the WorkflowRuntime object is no longer in a using block, so it can remain in memory, not disposed, while the workflow instance is running on the background thread.

The workflow instance is created the same as before, and its Start() method is called. At that point this method simply ends, returning to the caller.

Once you call BeginWorkflow() the workflow is started on a background thread, but your current thread (often the UI thread) is free to continue working.

The final piece to the puzzle is a method your application can call before it exits, or when it otherwise can’t continue without the workflow having completed:

    public static void EndWorkflow()

    {

      // wait for workflow to complete

      _waitHandle.WaitOne();

 

      // dispose runtime

      _workflowRuntime.Dispose();

 

      if (_workflowError != null)

        throw _workflowError;

    }

It is important to realize that this method will block the current thread until _waitHandle is set. If the workflow completes before this method is called, then _waitHandle is already set, and this method runs immediately, but if the workflow is still running, this method will block until the workflow completes or terminates.

For this to work, you must call EndWorkflow() before your process terminates to properly dispose the runtime and to determine if the workflow terminated unexpectedly.

 

Wednesday, August 01, 2007 4:15:26 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 

 Tuesday, July 31, 2007

Srinivas Surampalli, a fellow Magenic consultant, just wrote the following article:

Using XML with Stored Procedures Effectively in SQL Server 2005

One common question that comes up relative to CSLA data access is how to efficiently save an object graph where there's a parent with children or even grandchildren.

The typical answer is to make an INSERT/UPDATE/DELETE call for the parent and each child. This article shows a different approach, where you could put the business object data into a DTO object graph, serialize that object graph into XML and make a single database call.

What surprised me, looking at the article's code, is that the SQL in the stored procedure is so straightforward.

As always, you should test different approaches to find the one that works best for your application, based on performance, maintainability and other requirements.

Tuesday, July 31, 2007 8:15:00 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [3]  | 

 Thursday, July 26, 2007

Visual Studio 2008 Beta 2, along with Microsoft .NET 3.5 Beta 2, is available for download. Here's Soma's official announcement.

I find that downloading such huge sets of files requires a bit of help. My recommendation: Free Download Manager. This tool is awesome - indispensable in fact - if you do any downloads beyond small text files :) It does queued downloads, resumed downloads and throttling. Perhaps best of all, it does multi-threaded downloads, so it maximizes the use of your bandwidth when running at full throttle.

Update: Apparently there are some things you must do/fix before using VS 2008!! Read ScottGu's blog post about it!

Update 2: According to Juval Lowy, the svcutil.exe program in Beta 2 is broken. A workaround is to copy an older (Beta 1?) version of svcutil.exe over the top of the Beta 2 version.  Instead, Justin Smith says that you need to run "sn.exe -Vr svcutil.exe" - apparently then you don't need to copy an older verison over the new one.

Thursday, July 26, 2007 3:21:37 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [2]  | 

Every time I go to override the Text property in a Windows Forms UserControl I have to go find this one little attribute that I can never remember...

It is easy enough to remember to make the property Browsable(true), but it is that other attribute that's hard to remember: DesignerSerializationVisibility(DesignerSerializationVisibility.Visible).

This web page not only answers the question, but includes a nice summary of all the System.ComponentModel attributes. 

At least next time I know I can search my own blog to find the answer :)

Thursday, July 26, 2007 8:47:34 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 

 Wednesday, July 25, 2007

Today I received a letter from a large (the largest?) US bank, offering me a special discount rate on charges made to my credit card.

To my knowledge, I have no account at this bank at all, including no such credit card. That’s never good!

So I called the number on the letter to find out what’s going on. Of course I got to the bank’s credit card service center, where they asked me my credit card number, let’s pick up there:

“That’s why I’m calling. I don’t have such a credit card” said I.

“I can look it up using your social security number” said she.

And this is when my brain finally kicked in. I had dialed the number from the suspicious letter!! While the letter looked authentic, and the automated answering system on their end sounded authentic, how did I actually know I was talking to this large bank?

“I’m not sure I want to provide that” I answered.

“Can I have you spell your name then?” she asked.

I did that, as my name is easily found, and the letter already had that. She then confirmed that I had an account with them, and asked “Can you confirm your birth date?”

“Umm, I’m not sure I want to provide that either. I need to look on the web site and see if your phone numbers match.”

“OK, can I put you on hold?”

“Sure.”

So I did. I went to their web site, clicked “Contact Us” and found different phone numbers. In the meantime she came back on the line.

“Did you find what you needed?” she asked.

“No, the numbers don’t match.”

“Well you have reached ____, and we do have an account in your name. If you provide your birthdate I can give you the account details.”

“Yeah, see that’s the problem. You can confirm my identity, but there’s nothing you can give me that can confirm your identity. I’m going to have to call the number on the web site to be sure.”

“This really is ____” she said in an exasperated tone.

“Well, I can’t be sure” I replied.

“Then do what you need to” she said, and hung up rather abruptly.

So I did call the number from the web site. I did have an account there. Some credit card I haven’t used since the middle of 2000. I was able to find that out without even talking to a human: their automated system handled the whole process, including my canceling the card.

But it sure goes to show just how complex bi-directional authentication can be. Makes a person really appreciate the work done to design Kerberos, SSL, Windows Card Services and all the other authentication schemes out there we take for granted every day…

Wednesday, July 25, 2007 2:45:17 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [3]  | 

 Thursday, July 12, 2007

Bil Simser tagged me with this meme, thanks Bil.

As I tend to do with these things, I'll answer, but I'm not going to pass it on.

Apparently the idea is to list 5 things that'll make me a better developer over the next 6 months. The problem is, I'm not sure being a better developer is my primary focus just at the moment. But here's my list:

Keep my head above water

Microsoft has recently, and continues into the foreseeable future, to come out with new technology releases at a ridiculous pace. By "head above water" all I really mean is that I want, at least, to have a general clue about the purpose and real capabilities of all the stuff they are throwing at us. Not just the marketing hype, but what it really means. This, to me, has always been one of my primary strengths: the ability to grok most of the technologies available, and to figure out how they fit into some overarching architecture/worldview/philosophy.

But the current rate of change, and the amount of redundancy (ADO.NET, DataSets, LINQ, ADO.NET EF all solving the same problem? Come on!) makes this increasingly challenging. So over the next 6 months I'll be reading, talking to experts (and anyone else with something to offer) and experimenting in the hopes of keeping my head above water.

CSLA .NET

I used to learn new technologies by writing games - specifically MUDs and then low-end MMORPGs (well, I wrote and rewrote parts of one that never really came together). Someday I'd like to get back to doing that.

But in the meantime, I have CSLA .NET, and it has grown enough over the years that it affords me the opportunity to explore most of the key technologies I really want to learn. Having just released version 3.0, I got to dig into the plumbing behind WPF data binding, and explore the details around how WCF supports client/server (which it does well btw). Now my sights are turned toward two targets: .NET 3.5 and Silverlight.

The new language features, and of course lINQ itself, are key areas of focus for CSLA .NET 3.5. Fun stuff, no doubts there!

And if Silverlight 1.1 gets just a few more features (most notably data binding to objects), I believe I can create a CSLA Light that will provide a meaningful subset of CSLA .NET functionality within the Silverlight environment. If that pans out, it will be quite exciting :)

Magenic

Working for Magenic is great! I really enjoy the company and the people I work with. Over the next few months I'll be conciously spending more time and energy working internally with Magenic. As noted above, Microsoft's technology release schedule is grueling, and I want to make sure Magenic's consultants have the opportunity to stay on top of everything. This not only means doing some internal training, but more importantly working to build up a base of expertise and the infrastructure so other people can do some of that training (formally or informally).

It is (in my view) entirely unrealistic for one person to be an expert on everything that's going on. How can you credibly span .NET, Windows, Web, AJAX, SOA, Silverlight, SharePoint, Biztalk, SQL, Windows Server 2008 and everything else? You can't. But Magenic can, because we have a large enough pool of people that there's a decent level of expertise in all these technologies spread across the company. My challenge, then, is to coordinate that expertise such that the experts are in a position to share their knowledge with everyone else who needs it.

Of course Magenic has five offices across the country, and so there's the interesting sub-challenge of enabling the sharing of expertise across geographic distance. Actually it isn't the knowledge sharing that's such a big deal (we have great forums, etc), but it is the sharing if passion that is harder - and yet is at least as important.

Don't burn out

I've been feeling seriously burned out of late. That's not good. Part of it is due to the way travel grates on me more all the time, but most of it is that I haven't spent time doing truly exploratory things for a very long time now. CSLA has become quite consuming, and so my spare time goes into the framework, when I could be working on a .NET MUD engine or something really fun like that (I have these cool prototypes for truly dynamic world behavior that I'd love to pull together into something real).

It is also the case that I'm terrible about taking vacations. If I vacation at home, I work. That's the primary drawback with having a home office - work is always right there. But with Smartphones and laptops with wireless and/or cell modems the "office" can go almost anywhere, so even with a traditional office, escape is almost impossible.

Except... In August I'm spending a full week (nearly 10 days) in or near the Boundary Waters in far northern Minnesota. No meaningful cell coverage, no Starbucks or anywhere like it that would have wireless. Just untold miles and miles of wilderness, canoing, camping and fishing. Yea!

Remember the passion

Have you ever played that "what if" game? The one where you ask youself what job you'd do if you didn't do your current job?

I always draw a blank. If I had to do something else it would actually be work, rather than what I do now, which is to get paid for my hobby.

This, by the way, is what bothers me most about outsourcing, or even the software factory concept. It is true that economic needs shift over time, and steel workers needed to get new skills to find new jobs (as an example). I suppose it is possible that many of those steel workers had a burning passion for their job. That working with steel was their hobby as well as their job. But I doubt it. Most people I know view work as work: as a way to make money so they can do what they really want to do in their off hours. On the other hand, most developers I know view work as fun - and a way to make money while having fun.

Economists are often dismissive toward us, saying that if our jobs go offshore that we can just learn new skills and find different jobs. What they fail to understand is that we'd be doing far more than switching jobs: we'd be giving up an entire way of life. We'd be moving from a world of creative inspiration to a world of soul-crushing tedium. Yes, I realize I'm probably being very condenscending toward people with "normal" jobs, but this is how I see the world... (Then again, maybe economists do realize the deep love we have for what we do, and they envy us and so feel no remorse in talking about the destruction of our way of life?)

In any case, I love aspects of technology (especially building distributed and/or quasi-autonomous systems). And I love teaching about development. These things have been my passion since long before I officially started my career (when I was just a teenager, I was teaching elementary school kids how to use those new-fangled computers (Apples with no floating point support)). And I love writing - I really am what JMS describes as an "author" (one cursed to write because they can't not write). I can't imagine not doing most of the things I do today.

I think that's the key: remember the passion. Remember the fun. Yes, work hard, but more importantly code well, and perhaps above all: have fun!

Thursday, July 12, 2007 10:38:00 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [5]  | 

 Tuesday, July 10, 2007

CSLA .NET Version 3.0 is now available for download! Listen to the official announcement on .NET Rocks!

CSLA .NET 3.0 includes numerous enhancements and features of value to all CSLA .NET users, and of course version 3.0 adds support for Microsoft .NET 3.0 features like WCF and WPF.

You can use CSLA .NET 3.0 on either Microsoft .NET 2.0 or Microsoft .NET 3.0.

Features for everyone

CSLA .NET 3.0 includes enhancements useful to all CSLA .NET 2.1.4 users, including these highlights:

Validation rules

  • PropertyFriendlyName – specify a friendly name to use when displaying broken rule text
  • Format – specify a format mask to use when displaying broken rule numeric values
  • StringMinLength – new validation rule method
  • DecoratedRuleArgs – useful for code generation of AddBusinessRules() methods
  • Fix bug with stopProcessing and rule priorities
  • RegEx – rule method now supports options for dealing with null values

Authorization

  • New CanExecuteMethod() functionality, similar to CanReadProperty() and CanWriteProperty()

Undo and Data binding

  • If edit levels get out of sync an exception is thrown, making debugging of Windows Forms data binding much easier

Interfaces

  • Cleaned up and rearranged interfaces to provide more consistency – making it easier to create UI frameworks on top of CSLA business layers

SmartDate

  • Added TryParse() method
  • Fix bug with CompareTo() method

SortedBindingList and FilteredBindingList

  • Allow access to underlying source list

BusinessListBase

  • Fix some bugs where ListChanged/CollectionChanged events were raised when they shouldn't have been. The result is that some data binding scenarios now work where they didn't, and in other cases performance is improved.

ProjectTracker\PTWin

  • Reworked data binding code to address all known issues

See the change log for a complete list of changes.

Again, CSLA .NET 3.0 can be used without Microsoft .NET 3.0. If you want to build CSLA .NET 3.0 without installing the Microsoft .NET 3.0 runtime, you must define the NET20 symbol in project properties.

Microsoft .NET 3.0 Features

Of course the primary focus of CSLA .NET 3.0 is support for Microsoft .NET 3.0. Highlights include:

CSLA .NET

  • WcfProxy – a data portal channel that uses WCF. You can transparently move from any existing data portal channel to WCF by using this new proxy.
  • DataContract – support for using the WCF DataContract and DataMember attributes in your business classes
  • WPF
    • CslaDataProvider – a data provider control that can create, fetch, save and cancel edits on a CSLA .NET business object. In some cases this can lead to code-less data entry forms!
    • Validator – a control that provides Windows Forms ErrorProvider-like behavior to WPF forms that are data bound to CSLA .NET objects.
    • Authorizer – a control that provides Windows Forms AuthorizeReadWrite-like behaviors to WPF forms that are data bound to CSLA .NET objects.
    • ObjectStatus – a control that exposes IsValid, IsSavable and other properties from a CSLA .NET business object so they can be used by XAML data binding.
    • IdentityConverter – a value converter that can be used to work around an issue with data binding and refreshing the UI.

The Csla solution is a Visual Studio 2005 solution. You can open and build the solution in Visual Studio 2005 if you have the Microsoft .NET 3.0 runtime installed on your workstation. Or you can use the NET20 symbol to allow compilation without the Microsoft .NET 3.0 runtime.

The Csla solution automatically upgrades when opened in Visual Studio 2008, and you can build the solution in Visual Studio 2008 if you are using that environment.

ProjectTracker\PTWpf

  • Added new WPF UI with equivalent functionality to PTWin.

Note that this project is built using Visual Studio 2008 (Orcas) Beta 1.

ProjectTracker\PTWorkflow

  • Added new Workflow UI to illustrate how a workflow can use CSLA .NET business objects

Note that this project is built using Visual Studio 2008 (Orcas) Beta 1.

ProjectTracker\PTWcfClient and PTWcfService

  • Added a WCF service illustrating how to expose CSLA .NET objects through WCF/SOA
  • Added a WCF client app illustrating how to call a WCF service

Note that these projects are built using Visual Studio 2008 (Orcas) Beta 1.

ProjectTracker\WcfHost

  • Added a WCF host for the data portal

Note that this project is built using Visual Studio 2005 with the WCF extensions installed.

The ProjectTracker solution includes WcfHost, but does not include the other new projects. The reason for this is that the ProjectTracker solution is still a Visual Studio 2005 solution, while these other projects are built using Visual Studio 2008. The ProjectTracker solution upgrades automatically when opened in Visual Studio 2008, and in that environment you can add the remaining projects to the solution.

Migration

Migrating from version 2.1.4 to 3.0 should be relatively painless.

The only place you may encounter issues is that version 3.0 throws an exception if your edit levels get out of sync when using n-level undo. This may highlight pre-existing bugs in your UI code (especially in Windows Forms apps) that you should resolve. Look at the ProjectTracker\PTWin code for examples of the correct way to interact with Windows Forms data binding.

Migrating from 2.0.x to 3.0 has the same challenges as moving from 2.0 to 2.1. Version 2.1 introduced some significant, but important, changes to the handling of validation and authorization rules that can impact your business object code. See the CSLA .NET Version 2.1 Handbook for detailed information about version 2.1.

Migrating from 1.x to 3.0 will require some effort. There are many new features in 2.1 and 3.0 as compared to 1.x, and taking advantage of those features requires changes to your business objects and your UI code. You can look at the Expert C#/VB 2005 Business Objects books and the CSLA .NET Version 2.1 Handbook to get details around the scope of the changes.

Futures

I plan to write an ebook showing how to use the new features and enhancements in CSLA .NET 3.0. This ebook should be available in the third quarter of 2007 (probably September).

I’m working on CSLA .NET 3.5, based on Microsoft .NET 3.5 and focused on LINQ and various other new .NET features. Look for this in the first quarter of 2008.

I am also planning to update my Expert Business Objects books for Visual Studio 2008 and CSLA .NET version 3.5. This will probably come out in the second quarter of 2008.

You can see the roadmap here.

Tuesday, July 10, 2007 8:56:10 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  | 

 Sunday, June 24, 2007

Just a quick reminder that the official 3 day CSLA .NET training roadshow continues through the summer. You can still attend in one of these cities:

  • Orlando
  • Chicago
  • Washington, DC
  • Dallas

The feedback from the classes so far has been excellent! I sat in on part of the class last week in Minneapolis, and I can see why. Miguel is a very good teacher, and his hands-on, continual lab style is a refreshing change from traditional powerpoint-heavy training.

Sunday, June 24, 2007 8:14:13 AM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [3]  | 

 Friday, June 22, 2007

CSLA .NET Version 3.0 Beta 2 is now available for download.

This is the final test release of version 3.0. Any changes between now and release will be bug fixes.

If you plan to upgrade please consider helping yourself and the community at large by downloading this version and testing it before July 5. Let me know about any issues through the forum.

CSLA .NET 3.0 provides support for Microsoft .NET 2.0 and 3.0.

If you want to build CSLA .NET 3.0 without .NET 3.0, you must define the NET20 symbol in the project properties.

CSLA .NET 3.0 includes enhancements useful to all 2.1.4 users, including these highlights:

Validation rules

·         PropertyFriendlyName – specify a friendly name to use when displaying broken rule text

·         Format – specify a format mask to use when displaying broken rule numeric values

·         StringMinLength – new validation rule method

·         DecoratedRuleArgs – useful for code generation of AddBusinessRules() methods

·         Fix bug with stopProcessing and rule priorities

·         RegEx – rule method now supports options for dealing with null values

Authorization

·         New CanExecuteMethod() functionality, similar to CanReadProperty() and CanWriteProperty()

Undo and Data binding

·         If edit levels get out of sync an exception is thrown, making debugging of Windows Forms data binding much easier

Interfaces

·         Cleaned up and rearranged interfaces to provide more consistency – making it easier to create UI frameworks on top of CSLA business layers

SmartDate

·         Added TryParse() method

·         Fix bug with CompareTo() method

SortedBindingList and FilteredBindingList

·         Allow access to underlying source list

ProjectTracker\PTWin

·         Reworked data binding code to address all known issues

See the change log for a complete list of changes.

Of course the primary focus of CSLA .NET 3.0 is support for Microsoft .NET 3.0. Highlights include:

·         WcfProxy – a data portal channel that uses WCF. You can transparently move from any existing data portal channel to WCF by using this new proxy.

·         DataContract – support for using the WCF DataContract and DataMember attributes in your business classes

·         WPF

o   CslaDataProvider – a data provider control that can create, fetch, save and cancel edits on a CSLA .NET business object. In some cases this can lead to code-less data entry forms!

o   Validator – a control that provides Windows Forms ErrorProvider-like behavior to WPF forms that are data bound to CSLA .NET objects.

o   Authorizer – a control that provides Windows Forms AuthorizeReadWrite-like behaviors to WPF forms that are data bound to CSLA .NET objects.

o   ObjectStatus – a control that exposes IsValid, IsSavable and other properties from a CSLA .NET business object so they can be used by XAML data binding.

o   IdentityConverter – a value converter that can be used to work around an issue with data binding and refreshing the UI.

ProjectTracker\PTWpf

·         Added new WPF UI with equivalent functionality to PTWin.

ProjectTracker\PTWorkflow

·         Added new Workflow UI to illustrate how a workflow can use CSLA .NET business objects

ProjectTracker\PTWcfClient and PTWcfService

·         Added a WCF service illustrating how to expose CSLA .NET objects through WCF/SOA

·         Added a WCF client app illustrating how to call a WCF service

ProjectTracker\WcfHost

·         Added a WCF host for the data portal

Friday, June 22, 2007 3:30:47 PM (Central Standard Time, UTC-06:00)  #    Disclaimer  |  Comments [0]  |