Friday, May 12, 2006

If you haven't looked into CSLA yet, you need to.  Rocky has done a lot of thinking about the concept of business objects, and his stuff works great.  The framework he gives you really helps write clean, efficient, reusable code. 

Take his business rules model as an example.  Simply override "AddBusinessRules" (it is called when an object is instantiated) and add any combination of predefined rules from the "CommonRules" class or create your own (e.g. "ValidateGroupId" or "ValidateType").  This standardizes a way to get the business logic out of the UI and into the business object where it belongs.  The great thing is that the logic is reusable.  It can run on any tier - from the UI to the application server (potentially even in the DB - probably NOT recommended.)  You can use the same object to show errors to the end user in a Win/WebForm application, an Avalon app, or validate data from a Web Service.

Rocky, of course, does a much better job explaining this than I ever could, so go check him out: http://www.lhotka.net/

Get the full explanation in his latest book: Expert C#/VB 2005 Business Objects

Here's a snippet from one of my business objects to help you see how it all fits together:


    Protected Overrides Sub AddBusinessRules()

 

        With Me.ValidationRules

            ' "To" is required but max of 50

            .AddRule(AddressOf CommonRules.StringRequired, "To")

            .AddRule(AddressOf CommonRules.StringMaxLength, _

                New CommonRules.MaxLengthRuleArgs("To", 50))

 

            ' "From" is required, but max of 50

            .AddRule(AddressOf CommonRules.StringRequired, "From")

            .AddRule(AddressOf CommonRules.StringMaxLength, _

                New CommonRules.MaxLengthRuleArgs("From", 50))

 

            ' GroupID must be > 0

            .AddRule(AddressOf Me.ValidateGroupId, "GroupId")

 

            ' Message is not required but max of 500

            .AddRule(AddressOf CommonRules.StringMaxLength, _

                New CommonRules.MaxLengthRuleArgs("Message", 500))

 

            ' Apply custom "Type" rules

            .AddRule(AddressOf ValidateType, "Type")

        End With

 

    End Sub

 

 

 

    Private Function ValidateGroupId( _

        ByVal target As Object, ByVal e As RuleArgs) As Boolean

 

        If _groupId < 1 Then

            e.Description = "Invalid Group ID"

            Return False

        End If

        Return True

 

    End Function

 

 

 

    Private Function ValidateType( _

        ByVal target As Object, ByVal e As RuleArgs) As Boolean

 

        If Me._items.Count > 0 _

        AndAlso Me.Type <> RequestType.Reviewer Then

            e.Description = _

                "When group items are listed, type must be ""Reviewer"""

            Return False

        ElseIf Me._items.Count = 0 _

        AndAlso Me.Type = RequestType.Reviewer Then

            e.Description = _

                "Type cannot be ""Reviewer"" when group items are not listed"

            Return False

        End If

        Return True

 

    End Function

 

Friday, May 12, 2006 6:39:51 PM (Central Daylight Time, UTC-05:00)  #    Disclaimer  |  Comments [1]  | 
 Thursday, May 11, 2006

I just got done updating my list of developer resources.  Have a look and let me know what I missed!

Thursday, May 11, 2006 4:29:05 PM (Central Daylight Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, May 10, 2006

Ever needed to do reflection over a generic type?  Look no further.  MSDN has a good explanation:

http://msdn2.microsoft.com/en-us/library/b8ytshk6(VS.80).aspx

Wednesday, May 10, 2006 3:37:22 PM (Central Daylight Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
 Tuesday, May 09, 2006

Well, it looks like Wal-Mart is claiming rights to "the smiley face." Which smiley face? All of them I guess... (http://news.bbc.co.uk/2/hi/business/4984138.stm - via Slashdot)

I guess I'm going to have to stop using smiley emoticons in my emails (or blog posts) :-)  I could get slapped with trademark infrigement or something. Also expect mass arrests among junior high girls. 

Kind of ironic that Wal-Mart's spokes person's last name is "Simley" which is easily mis-read "Smiley"

Tuesday, May 09, 2006 4:34:02 PM (Central Daylight Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  | 
 Wednesday, May 03, 2006

Jessica Fosler recently posted a great summary on common causes for .NET memory leaks ("You gotta learn to let it go: Top 4 memory leaks").  If you're leaking memory, I'd strongly suggest this as as starting point.

In my experience, static/shared events are the most likely culprit.  Anytime you're dealing with a static event, check and double-check to make sure you're unregistering your handlers during cleanup.  Here's what Jessica says about it:

Make sure you know who you're giving your object out to. If you're stuffing your object in a static (or shared) list, it should be removed at some point in time, as that shared list will hold open the lifetime of your object.

This also goes for hooking onto static events.  (I've mentioned this one before.)  The most common culprits are SystemEvents.UserPreferenceChanged and Application.Exit, Application.Idle etc.  If you're hooking onto these events, remember to unhook when you're ready for cleanup, otherwise the Application and/or SystemEvents class will keep your object alive.

Wednesday, May 03, 2006 5:00:15 PM (Central Daylight Time, UTC-05:00)  #    Disclaimer  |  Comments [0]  |