CSLA 2.1.3 C# templates bugs

CSLA 2.1.3 C# templates bugs

Old forum URL: forums.lhotka.net/forums/t/2252.aspx


tiago posted on Wednesday, January 31, 2007

1 - Templates.csproj is missing DynamicRootList.cs

2 - DynamicRootList.cs

public class DynamicRootList : EditableRootListBase<DynamicRootList, EditableRoot>

VS 2005 claims it cannot resolve symbol EditableRootListBase

tiago replied on Wednesday, January 31, 2007

BTW, it's easy to add templates

1 - open the solution file

2 - File -> Export template
as Project template (see EDIT note)

3 - Open each one of the project files

4 - For each file, File -> Export template
as Item template

It's also easy to use templates

A - Project templates

File -> New -> Project (look under C# - My templates) (see EDIT note)

B - Item templates

There are 3 ways of using an item template:

- On Solution Explorer, right click on a project and Add -> New Item

- Project -> Add New Item

- just press CTRL+Shift+A

On either case, an Add New Item - Shell window will open. Scroll it down until the My templates area shows

EDIT: I think it doesn't make sense to use CSLA templates as a project template, but just as item templates.

DansDreams replied on Friday, February 02, 2007

Wow!  Thanks man. 

Since I have tweaked my base business objects (inheriting from Rocky's), I looked into creating templates a while back and got lost in trying to find where to even start from the documentation.

Was I just looking in the wrong place or is this a new VS2005 feature?

tiago:

BTW, it's easy to add templates

<snip>

tiago replied on Friday, February 02, 2007

DansDreams:

Wow!  Thanks man. 

Since I have tweaked my base business objects (inheriting from Rocky's), I looked into creating templates a while back and got lost in trying to find where to even start from the documentation.

Was I just looking in the wrong place or is this a new VS2005 feature?

I didn't install SP1 on VS 2005 so I guess this isn't a new feature. But then again I also started by looking in the wrong place ;)

BTW I re-think the whole thing, it doesn't make sense to use CSLA templates as project templates

Rocky, wasn't there a FAQ thread? I think the how-to-use-templates part should go there.

RockfordLhotka replied on Friday, February 02, 2007

There is an FAQ thread at the top of the forum. If you write up a blurb I’ll gladly add it to the FAQ.

 

Thanks, Rocky

 

From: tiago [mailto:cslanet@lhotka.net]
Sent: Friday, February 02, 2007 5:02 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Using templates is easy

 

DansDreams:

Wow!  Thanks man. 

Since I have tweaked my base business objects (inheriting from Rocky's), I looked into creating templates a while back and got lost in trying to find where to even start from the documentation.

Was I just looking in the wrong place or is this a new VS2005 feature?

I didn't install SP1 on VS 2005 so I guess this isn't a new feature. But then again I also started by looking in the wrong place ;)

BTW I re-think the whole thing, it doesn't make sense to use CSLA templates as project templates

Rocky, wasn't there a FAQ thread? I think the how-to-use-templates part should go there.



tiago replied on Friday, February 02, 2007

Got the SVNed version of DynamicRootList.cs

VS 2005 still doesn't like it

using System;
using System.Data.SqlClient;
using Csla;

[Serializable()]
public class DynamicRootList : EditableRootListBase<EditableRoot>

On Build -> Run Code Analysis on Templates I get the error The type or namespace name 'EditableRoot' could not be found (are you missing a using directive or an assembly reference?)

VS2005 sugests adding:
using Templates;

another round of Code Analysis reports Inconsistent accessibility: base class 'Csla.EditableRootListBase<Templates.EditableRoot>' is less accessible than class 'DynamicRootList'

RockfordLhotka replied on Friday, February 02, 2007

Fwiw, it isn’t my intent that the templates project actually build. I only created it as a project for my own convenience when editing the template files.

 

Rocky

 

From: tiago [mailto:cslanet@lhotka.net]
Sent: Friday, February 02, 2007 6:05 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: Using templates is easy

 

Got the SVNed version of DynamicRootList.cs

VS 2005 still doesn't like it

using System;
using System.Data.SqlClient;
using Csla;

[Serializable()]
public class DynamicRootList : EditableRootListBase<EditableRoot>

On Build -> Run Code Analysis on Templates I get the error "The type or namespace name 'EditableRoot' could not be found (are you missing a using directive or an assembly reference?)"

VS2005 sugests adding:
using Templates;

another round



tiago replied on Saturday, February 10, 2007

1-Add Templates to using section
2-DynamicRootList shouldn't be public

tiago:
using System;
using System.Data.SqlClient;
using Csla;
using Templates;

[Serializable()]
class DynamicRootList : EditableRootListBase<EditableRoot>

Now there is this problem with DataPortal_Fetch()

private void DataPortal_Fetch()
{
    // TODO: load values
    RaiseListChangedEvents = false
;
    using (SqlDataReader dr = null
)
    {
        while
(dr.Read())
        {
            Add(
EditableRoot
.GetEditableRoot(dr));
        }
    }
    RaiseListChangedEvents = true
;
}

EditableRoot.GetEditableRoot expects an int argument, not a SqlDataReader argument. I guess we must overload EditableRoot.GetEditableRoot.

tiago replied on Sunday, February 11, 2007

Stupid me!

insteaf of:

using System;
using System.Data.SqlClient;
using Csla;
using Templates;

[Serializable()]
class DynamicRootList : EditableRootListBase<EditableRoot>
{
...
}

use:

using System;
using System.Data.SqlClient;
using Csla;

namespace Templates
{
   [
Serializable()]
   internal
class DynamicRootList : EditableRootListBase<EditableRoot>
   {

....
   }
}

The namespace Templates will be replaced by the actual namespace you are working on.

The change to internal is for consistency sake as all templates use internal classes.

tiago replied on Saturday, February 24, 2007

Csla 2.1 introduced EditableRootListBase. You can read the change log at  http://www.lhotka.net/Article.aspx?area=4&id=f12cc951-0452-42d1-96a6-cfa7656863b1

This new Csla base class is fully documented on the 2.1 e-book.

 

The template for DynamicRootList objects (as Rocky named objects that use the new base class) is buggy. After some atempts, I think I got it right.

DynamicRootList.cs

using
System;
using
System.Data.SqlClient;
using
Csla;

namespace
Templates
{
   [
Serializable
()]
   
internal class DynamicRootList : EditableRootListBase<EditableRoot
>
   
{

      
#region
Authorization Rules

      
public static bool
CanGetObject()
      {
         
// TODO: customize to check user role
         
return ApplicationContext.User.IsInRole(""
);
      }

      public static bool CanEditObject()
      
{
         
// TODO: customize to check user role
         
return ApplicationContext.User.IsInRole("");
      
}

      
#endregion

      
#region
Factory Methods

      
public static DynamicRootList NewDynamicRootList()
      
{
         
return new DynamicRootList();
      
}

      
public static DynamicRootList GetDynamicRootList()
      
{
         
return DataPortal.Fetch<DynamicRootList>();
      
}

      
private DynamicRootList()
      
{
         
// require use of factory methods
      
}

      
#endregion

      
#region
Data Access

      
private void DataPortal_Fetch()
      
{
         
// TODO: load values
         
RaiseListChangedEvents = false;
         
using (SqlDataReader dr = null)
         
{
            
while (dr.Read())
            
{
               
Add(
EditableRoot.GetEditableRoot(dr));
            
}
         
}
         
RaiseListChangedEvents =
true;
      
}

      
#endregion

   
}
}

The problem is DataPortal_Fetch calls EditableRoot.GetEditableRoot with a SqlDataReader type parameter while that method is expecting an int parameter. On EditableRoot.cs we need an overload to GetEditableRoot and some other new methods. All changes are marked with a red side bar.

EditableRoot.cs

using
System;
using System.Collections.Generic;
using
System.Text;
| using System.Data.SqlClient;
using Csla;

namespace
Templates
{
   [Serializable
()]
   class EditableRoot : BusinessBase<EditableRoot
>
   {

      #region
Business Methods

      // TODO: add your own fields, properties and methods

      private int
_id;
|     private string _data = string.Empty;

      public int id
      
{
         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions
.NoInlining)]
         
get
         
{
            CanReadProperty(true
);
            return
_id;
         
}

         [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.NoInlining)]
         
set
         {
            CanWriteProperty(true);
            if (_id != value)
            {
               _id = value;
               PropertyHasChanged();
            }
         }
      }

|     public string Data
|     {
|        [System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions
.NoInlining)]
|        
get
|        
{
|           CanReadProperty(true
);
|           return
_data;
|        
}
|     }

      protected override object GetIdValue()
      
{
         return
_id;
      
}

      
#endregion

      #region
Validation Rules

      protected override void
AddBusinessRules()
      
{
         
// TODO: add validation rules
         //ValidationRules.AddRule(null, "");
      
}

      
#endregion

      #region
Authorization Rules

      protected override void
AddAuthorizationRules()
      
{
         
// TODO: add authorization rules
         
//AuthorizationRules.AllowWrite("", "");
      
}

      public static bool
CanAddObject()
      
{
         
// TODO: customize to check user role
         
//return ApplicationContext.User.IsInRole("");
         
return true
;
      
}

      public static bool
CanGetObject()
      
{
         
// TODO: customize to check user role
         
//return ApplicationContext.User.IsInRole("");
         
return true
;
      
}

      public static bool
CanEditObject()
      
{
         
// TODO: customize to check user role
         
//return ApplicationContext.User.IsInRole("");
         
return true
;
      
}

      public static bool
CanDeleteObject()
      
{
         
// TODO: customize to check user role
         
//return ApplicationContext.User.IsInRole("");
         
return true
;
      }

      
#endregion

      #region
Factory Methods

      public static EditableRoot
NewEditableRoot()
      {
         return DataPortal.Create<EditableRoot
>();
      }

      public static EditableRoot GetEditableRoot(int
id)
      {
         return DataPortal.Fetch<EditableRoot>(new Criteria
(id));
      }

      public static EditableRoot GetEditableRoot(SqlDataReader
dr)
      {
         return new EditableRoot
(dr);
      }

      public static void DeleteEditableRoot(int
id)
      {
         DataPortal.Delete(new Criteria
(id));
      }

      private
EditableRoot()
      {
         /* Require use of factory methods */
      
}

|     private EditableRoot(SqlDataReader dr)
|     {
|        Fetch(dr);
|     }

      #endregion

      #region
Data Access

      [Serializable
()]
      private class
Criteria
      
{
         private int
_id;
         public int
Id
         {
            get { return
_id; }
         }

         public Criteria(int
id)
         {
            _id = id;
         }
      }

      protected override void
DataPortal_Create()
      {
         
// TODO: load default values
      
}

      private void DataPortal_Fetch(Criteria
criteria)
      {
         
// TODO: load values
      
}

      protected override void
DataPortal_Insert()
      {
         
// TODO: insert values
      
}

      protected override void
DataPortal_Update()
      {
         
// TODO: update values
      
}

      protected override void
DataPortal_DeleteSelf()
      {
         DataPortal_Delete(new Criteria
(_id));
      }

      private void DataPortal_Delete(Criteria
criteria)
      {
         
// TODO: delete values
      
}

|     private void Fetch(SqlDataReader dr)
|
     {
|        
// load values
|        _id = dr.GetInt32(0);
|        _data = dr.GetString(1);
|     }

      
#endregion
   }
}

gdk9am replied on Wednesday, January 31, 2007

To solve point number 2, add "using Csla;:" to "using" region

tiago replied on Wednesday, January 31, 2007

gdk9am:
To solve point number 2, add "using Csla;:" to "using" region

VS 2005 reports: "Incorrect number of type parameters in reference to class 'Csla.EditableRootListBase<T>'

RockfordLhotka replied on Wednesday, January 31, 2007

Thanks for catching that, I've fixed the project reference and code in svn, so it will be in the next release.

gdk9am replied on Wednesday, January 31, 2007

In your CSLA .NET Version 2.1 Handbook C# version, the class template of "EditableRootListBase" also has the smae problem

RockfordLhotka replied on Wednesday, January 31, 2007

Yes, that's the one we're talking about I believe.

Copyright (c) Marimer LLC