Sunday, December 07, 2008

I admit that while I have been keeping up with Csla information, I haven't had the opportunity to use the newer versions of Csla.  We have an opportunity to use Csla with a client so I'm using this chance to catch up on it and get some practical experience with 3.6.  I downloaded the framework and samples downloads. You can download the latest framework at http://www.lhotka.net/cslanet/Download.aspx

I was excited by how much is included in both.  The framework includes snippets, visual studio templates, and a deployment package.  Here's some highlights.

Snippets
There are several snippets included. With the new way to do properties in Csla, the editable and readonly property snippets will come in handy.  Here's the results of the "cslaprop" snippet.

private static PropertyInfo<int> NameProperty = RegisterProperty(new PropertyInfo<int>("Name", "Name"));

public int Name
{
   get { return GetProperty(NameProperty); }
   set { SetProperty(NameProperty, value); }
}

Item Templates
When you install the VSI, it installs 14 templates for almost all common Csla usages and objects.  Like the rest of the framework, the full source for the templates are included.  So customizing the templates to fit your projects needs is easy.

 

Csla Samples
I downloaded the samples project expecting to just see the Project Tracker example.  The Project Tracker is still the main example but it has been expanded to include examples for every configuration that Csla supports including WCF, Web Services, WPF, winforms, Webforms, Silverlight (requires additional Csla for Silverlight download), LINQ, DTO, Entity Framework, Workflow, etc.

In addition to the Project Tracker, there are examples for doing WPF design time support, Deep loading and saving of data, and establishing parent-child-grandchild relationships in Csla. 

I am looking forward to working through all of these examples to see Rocky's recommendations in the 3.6 version of his framework.

Mike
 

Sunday, December 07, 2008 6:17:28 PM (Central Standard Time, UTC-06:00)  #    Comments [0]  | 
Tuesday, January 22, 2008

The CSLA.NET books have some guidance for reports, but I have found that a little different solution has worked better for us.  Reports usually have some similar characteristics. 

  • The are read only.  Static data.
  • Logic for reports are usually in stored procs.
  • Usually different than the standard business object formats.

So I got a little push back and I didn't quite like the idea of creating a seperate business object for each report.  We weren't using any validation or code generation.  However, I didn't want to lose some of the power of CSLA.NET like the DataPortal.  I didn't want to use just classic data access and use datasets directly from the database. 

We came up with a hybrid report business object.  Instead of calling the data access directly, we used the dataportal_fetch and put the logic in there like a normal business object.  However this object only has one property, ReportDataSet.  This still allows us to use remoting or WCF if we want a middle tier.  Each report then is a new Factory method passing in a custom criteria object including the stored proc name and a parameters collection.

The returned object's dataset property then can be bound to the report.  The only thing we lose is property names.

Below is basic example of a ReportFactory class.

-Mike

using System;

using System.Collections.Generic;

using System.Text;

using System.Data;

using System.Data.SqlClient;

using System.Collections.Specialized;

 

namespace BusinessObjects

{

    public class ReportFactory : Csla.BusinessBase<ReportFactory>

    {

 

        private DataSet reportDataSource;

        public DataSet ReportDataSource

        {

            get { return reportDataSource; }

        }

 

        public static ReportFactory GetMonthEndTotalsReport(int Month, int Year)

        {

            ReportCriteria criteria = new ReportCriteria();

            criteria.SPName = "usp_MonthEndTotalsReport";

            criteria.SQLParameters.Add("@Month", Month);

            criteria.SQLParameters.Add("@Year", Year);

 

            return Csla.DataPortal.Fetch<ReportFactory>(criteria);

        }

 

 

        [Serializable()]

        protected class ReportCriteria

        {

            public string SPName = "";

            public ListDictionary SQLParameters = new ListDictionary();

 

        }

 

        protected void DataPortal_Fetch(ReportCriteria criteria)

        {

            using (SqlConnection conn = new SqlConnection(Database.Connection))

            {

                conn.Open();

                using (SqlCommand cm = conn.CreateCommand())

                {

                    cm.CommandType = CommandType.StoredProcedure;

                    cm.CommandText = criteria.SPName;

                    foreach (string param in criteria.SQLParameters.Keys)

                    {

                        cm.Parameters.AddWithValue(param, criteria.SQLParameters[param]);

                    }

                    reportDataSource = new DataSet();

 

                    using (SqlDataAdapter da = new SqlDataAdapter(cm))

                    {

                        da.Fill(reportDataSource);

                    }

                }

            }

        }

 

        protected override object GetIdValue()

        {

            return Guid.NewGuid();

        }

    }

}

Tuesday, January 22, 2008 6:18:28 AM (Central Standard Time, UTC-06:00)  #    Comments [0]  | 
Saturday, July 21, 2007

Our business problem:  We have properties that are required only when the status code is particular statuses.  This caused us to look at how to dynamically add/remove Validation Rules.

Here’s a small example of the different pieces.  I can’t include the full class because my work doesn’t like me to post that much code.  This should show you the main parts.   The only change to CSLA.NET that I can remember is that we had to make the ValidationRules public so we could call the AddRule and DeleteRule from outside the business object. 

 

In the Extended Property of the FullName column:

        Name  = IsRequiredForStatus
   
Value = Codes.Status.Complete

Property is generated like this:

   <IsRequiredForStatus(Codes.Status.Complete)> _

   Public Overridable Property FullName() As String

In the “set” of the nogen Status property (which is of type Codes.Status  enumeration), it calls the function to check the attributes.  This calls the EVIL attributes to process the rules:

   RunValidationAttributes()

In the Validator, it uses reflection to get all of the properties of the object. It loops through each of the properties and checks to see if any of the attributes are of type VBEvilBaseAttribute.  If so then it calls the ProcessRule of that attribute class such as “IsRequiredForStats”.

 

   Public Class IsRequiredForStatus

       Inherits VBEvilBaseAttribute

 

   Public Overrides Function ProcessRule(ByVal pi As PropertyInfo,

       ByVal entity As Object) As Boolean

 

If the property’s attribute enumeration value matches the enumeration of the Status property then it’s required.  The logic below is done for each datatype.

 

 If IsRequired Then

    If pi.PropertyType Is GetType(String) Then

      Dim args As New Csla2.Validation.RuleArgs(pi.Name)

      args.Description = pi.Name & " is required for this status."

      args.Severity = Csla2.Validation.RuleSeverity.FailsCustomRules

busObject.ValidationRules.AddRule(AddressOf

           Csla2.Validation.CommonRules.StringRequired, args)

 Else

    If pi.PropertyType Is GetType(String) Then

       busObject.ValidationRules.DeleteRule(pi.Name, "StringRequired")

If you have any questions, comments, or better ideas, please let me know.  I always like to hear ideas for using CSLA.NET. I would like to thank Dave Cottle.  He is the one that figured out a lot details to make this work.

Mike

Code Smart Not Hard

Saturday, July 21, 2007 2:50:13 PM (Central Standard Time, UTC-06:00)  #    Comments [0]  | 
Friday, June 15, 2007

I have seen several people searching for this that have reached my site.  The thought of getting the best of both SubSonic and CSLA.NET worlds has started to intrigue me.   I previous took the Subsonic templates for granted but I have spent a lot of time modifying my CSLA.NET templates and the framework.  So I am going to follow these steps to figure out how possible it was and if it really makes sense once it is done.

1.        Research the subsonic templates.  I haven’t looked at these much so I’m going to look through these to find comparisons and the differences between my CSLA.NET templates

2.       Since I obviously can’t inherit from both ActiveList/ActiveRecord and BindingListBase and BindingBase, I have to figure out what the hierarchy should be.  I am suspecting that there is a lot of common code between the two, especially when it comes to the binding and implementing the IList, IBindingLIst, etc  interfaces.

3.       Once I have the framework ready for my template, I am going to take the VB_ClassTemplate and modify it to include both references and inherit from the new base.

I should be able to have some stuff figured out over the weekend.   I’ll post the results and some downloads.  Feel free to send me your thoughts on  what you think the hybrid templates should look like.

Code Smart Not Hard

-Mike

Friday, June 15, 2007 10:54:20 PM (Central Standard Time, UTC-06:00)  #    Comments [0]  | 
Friday, June 08, 2007

 

Objects that are tightly coupled to the table that they reflect can be referred to as DataObjects.  BusinessObjects, however are objects that represent a logic unit contain the attributes and methods of the business object.  Using CSLA.NET, CodeSmith Tools for code generation, and partial classes in .NET 2.0 we are able to take the benefits of code generation and a straightforward DAL with the flexibility and options needed for designing Business Objects.   Below are some of the features of my templates that allow me to generate my Business Objects based on table schema but still allow flexibility

Partial Classes

Partial Classes is a key feature to my entire code generation process. The golden rule for generating code is to “Never edit generated code”.  With partial classes this is easy.  All of my custom functionality can be put in to my “NoGen” partial class file.  All of the other features actually contol how and what is generated but I included partial classes because it really is fundamental to code generation and allows unlimited custom functionality added to a pure DataObject.

Foreign Key Fields

This started out a way to display both the key and value data of a code in a particular row.  For example if I had an Employee table with a RoleID column, I could add a RoleName “Foreign Key Field” to the template properties.  This would generate the property just like it was a column in the table.  It is really handy for binding drop down lists to your business object and wanting to display the text value somewhere else without having to go look it up again.  This feature started out as always generating the property as a string and has grown into a delimited array where I specify the column and the datatype.  Keep in mind this will generate code for the fetch, update, and insert logic.

Require Gen  Column

Sometimes I don’t want the property to be generated but I still want the fetch, insert, and update data portal functions generated.  In this case, I specify in my template properties, to skip particular property generation. Then I can create the custom property in the no-gen partial class.  One example for this is if you have a lookup id field in your table and want the property to be an enumeration instead of an integer.

“GenOnly” Tables

“GenOnly” tables are tables that I create to base my object when the data isn’t in the format I want the data displayed.  For example I had a table with 6 columns each with a date.  If I bound this to a grid, each data for a particular row would display across in column s.  However the users wanted to see each date in its own row.  I couldn’t change the format the data is stored, so I created a “GenOnly” table with the schema in the format I wanted.

MyDates Table

·         MyDateID

·         Year1Date

·         Year2Date

·         Year3Date

·         Year4Date

·         Year5Date

·         Year6Date

GenOnly_MyDates

·         MyDateID

·         YearNumber

·         YearDate

Now I can use my templates to generate my readonly collection and object classes based on the “GenOnly” table.  I then create the SELECT stored procedure to pivot the data into the format of my objects.  Lastly I can load the objects and bind it to my grid so the data displays down.  In this example the data is readonly so I didn’t need to worry about deletes and updates.  However, if I needed to that I could create the UPDATE and DELETE procs to use a CASE statement or some dynamic SQL.

I like to think you can get the best of both worlds in using a code generator to generate your objects based on table schema but still have some flexibility because something will be different. 

Code Smart Not Hard

Mike

Friday, June 08, 2007 9:54:10 PM (Central Standard Time, UTC-06:00)  #    Comments [0]  | 
Thursday, March 15, 2007

A little over a year ago I presented at the Omaha.NET User Group meeting about using CSLA.NET and Codesmith.   My team and I have been using these two products together in a project for over a year now.   I absolutely believe these two products have contributed to the success of the projects.  

CSLA.NET gives us

  • Unlimited Undo
  • Binding to UI Controls
  • Base Collection and Editable Objects with CRUD
  • Broken rules notification to client via IDataErrorInfo
  • Remoting / Direct Data Access with only config change
  • much more!

We extended CSLA and features provided by our templates

  • Standard business rules through extended properties in SQL Server like MinLength, MaxLength, ReadOnly, IsRequired, etc
  • Custom business rules for any property by overriding AddCustomBusinessRules()
  • Add any custom code in partial classes
  • Parent object can contain 0 to many children collections
  • CRUD stored procs are generated
  • Load Multiple levels at once so that there is only one round trip to the server
  • Created SortedFilteredView object to act like a DataView
  • Custom column formatting for grids in our business objects

Take a look at the zip file attached.   I included the demo and the slides I used in the presentation.

CSLA2Demo.zip (1.34 MB)

If you have any questions or comments you can email me at  mike *at* doitconsultants.com

Mike

Thursday, March 15, 2007 9:44:58 PM (Central Standard Time, UTC-06:00)  #    Comments [0]  | 

Theme design by Jelle Druyts

Pick a theme: