LLBLGEN Support

LLBLGEN Support

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


Jayachandran posted on Thursday, July 24, 2008

Hi Rocky,

I'm new to CSLA.NET framework. We are planning to change our application architecture to use CSLA now. but our existing application is using LLBLGEN as DAL component. Does CSLA Support LLBLGEN?

I have seen JCL Framework, which uses CSLA and LLBLGEN but it seems no support and latest updates are available now.

Please guide me how to extend the CSLA support for LLBLGEN?

Thanks,
Jay

Patrick replied on Sunday, July 27, 2008

Hi Jay,

we are going the same path of trying to use LLBLGen with CSLA.NET.

In our current implementation we code generates a template for a business object based on the LLBLGen entities. We then copy & paste the code into our business classes :)

Then we use a mapping function to map the fields in the DataPortal Methods.

I attached the LLBLGen template for you as they might help you to get started.

Good luck,
Patrick

------------------
[Transactional(TransactionalTypes.TransactionScope)]
protected override void DataPortal_Insert()
{
    Persist(true);
}

[Transactional(TransactionalTypes.TransactionScope)]
protected override void DataPortal_Update()
{
    Persist(false);
}

protected void Persist(bool isNew)
{
    var entity = new AssignmentEntity();
    entity.IsNew = true;
    MapBoToEntity(entity);

    using (DataAccessAdapter da = new DataAccessAdapter())
        da.SaveEntity(entity, true, new PredicateExpression(AssignmentFields.LastChangeOn == mTimestamp));

    MapEnityToBo(entity);
}

// ------------------    CODE GENERATED BY LLBLGEN -------------

// Property: AssignmentId
public static CfxPropertyInfo<System.Int32> AssignmentIdProperty = RegisterProperty<System.Int32>(
    new CfxPropertyInfo<System.Int32>("AssignmentId", "AssignmentId", Globals.GroupCategoryType.Internal));
public System.Int32 AssignmentId
{
    get { return GetProperty<System.Int32>(AssignmentIdProperty); }
    set { SetProperty<System.Int32>(AssignmentIdProperty, value); }
}

// Property: ClassTypeId
public static CfxPropertyInfo<System.String> ClassTypeIdProperty = RegisterProperty<System.String>(
    new CfxPropertyInfo<System.String>("ClassTypeId", "ClassTypeId", Globals.GroupCategoryType.Internal));
public System.String ClassTypeId
{
    get { return GetProperty<System.String>(ClassTypeIdProperty); }
    set { SetProperty<System.String>(ClassTypeIdProperty, value); }
}


#region Data Access - Map
protected virtual void MapBoToEntity(DAL.EntityClasses.AssignmentEntity entity)
{
    entity.AssignmentId = ReadProperty<System.Int32>(AssignmentIdProperty);
    entity.ClassTypeId = ReadProperty<System.String>(ClassTypeIdProperty);
}

protected virtual void MapEnityToBo(DAL.EntityClasses.AssignmentEntity entity)
{
    LoadProperty<System.Int32>(AssignmentIdProperty, entity.AssignmentId);
    LoadProperty<System.String>(ClassTypeIdProperty, entity.ClassTypeId);
}
#endregion

// ------------------    CODE GENERATED BY LLBLGEN -------------

Jayachandran replied on Tuesday, July 29, 2008

Thanks Patrick, We will generate the LLBLGEN code using your template and let you know.

Regards,
Jay

Jayachandran replied on Monday, August 04, 2008

Hi Patrick,

We have generated the LLBLGEN code using your template and when trying to compile it gives an error saying "The type or namespace name 'CfxPropertyInfo' could not be found". Where can this class be found?

Also LLBLGen generates Nullable columns in the database as .net nullable datatype. Does CSLA supports for nullable data type?

Please suggest us.

Thanks,
Jay

Patrick replied on Wednesday, August 06, 2008

Jayachandran:
we have generated the LLBLGEN code using your template and when trying to compile it gives an error saying "The type or namespace name 'CfxPropertyInfo' could not be found". Where can this class be found?

We just extended ProperyInfo. I thought I had taken it out of the template sorry about that. Just remove the Cfx from the template and you should be fine.

This:
public static CfxPropertyInfo<System.Int32> AssignmentIdProperty = RegisterProperty<System.Int32>(
    new CfxPropertyInfo<System.Int32>("AssignmentId", "AssignmentId", Globals.GroupCategoryType.Internal));

should look like this:
public static PropertyInfo<System.Int32> AssignmentIdProperty = RegisterProperty<System.Int32>(
    new PropertyInfo<System.Int32>("AssignmentId", "AssignmentId"));

Jayachandran:
Also LLBLGen generates Nullable columns in the database as .net nullable datatype. Does CSLA supports for nullable data type?

Search for ShipVia on this page to see a way of using Nullable columns with CSLA.NET
http://forums.lhotka.net/forums/post/24092.aspx. It's easy to add it to the template.

All the best,
Patrick

Jayachandran replied on Thursday, August 07, 2008

Excellent, Works well

Many thanks Patrick Smile [:)]

Regards
Jay

Patrick replied on Saturday, August 09, 2008

Here another bonbon Smile [:)]

You can implement some basic business rules automatically:

// Implement your own business base class your business objects inherit from

[Serializable()]
public abstract class CfxBusinessBase<T> : global::Csla.BusinessBase<T> where T : CfxBusinessBase<T>
{
    public global::Csla.Core.IPropertyInfo GetPropertyInfo(string propertyName)
    {
        foreach (global::Csla.Core.IPropertyInfo ipropertyInfo in FieldManager.GetRegisteredProperties())
        {
            if (ipropertyInfo.Name == propertyName) return ipropertyInfo;
        }
        return null;
    }
}

// Validation Rules inside your business object

protected override void AddBusinessRules()
{
    var t = new DAL.FactoryClasses.ProjectEntityFactory();
    foreach (EntityField2 llblGenField in t.CreateFields())
    {
        if (llblGenField.IsPrimaryKey) continue;
        CslaCore.IPropertyInfo cslaProp = GetPropertyInfo(llblGenField.Name);
        if (cslaProp == null) continue;
        if (llblGenField.DataType == typeof(Boolean)) continue;
        if (llblGenField.MaxLength > 0) ValidationRules.AddRule(CslaVal.CommonRules.StringMaxLength, new CslaVal.CommonRules.MaxLengthRuleArgs(cslaProp, llblGenField.MaxLength));
        if (!llblGenField.IsNullable) ValidationRules.AddRule(CslaVal.CommonRules.StringRequired, new CslaVal.RuleArgs(cslaProp));
    }
}

Enjoy,
Patrick
 

fedge replied on Thursday, November 20, 2008

Hi Patrick,

Thanks for your post.

I've been using llblgen for a while, and would like to look into putting CSLA on top of it.

How has your experiment gone since this last post?  did it pan out well?

Just looking for some views on this before potentially re-inventing the wheel :)

Thanks

Matt

cds replied on Friday, November 21, 2008

Hi Matt and Jay (and Patrick)

A couple of years ago I wrote a plug-in to LLBLGen Pro that would allo CSLA Business Object classes to be designed and code-generated (using the LLBLGen code generator) from inside LLBLGen. This had the advantage of being able to design your Business Object classes by mapping them to fields of LLBLGen entities - but didn't restrict you to doing only this. It used the LLBLGen project as the metadata source for populating lists, etc. in the plug-in UI. The big advantage was automatic codegen of the data access logic that connected the CSLA business objects to the LLBLGen entity classes. (But it also had hooks allowing you to customise, add pre-fetch paths, filter, etc.)

Anyway, that was a couple of years ago (and I changed jobs after that) and was back in CSLA 2.6 days. Patrick is interested in me updating this to use CSLA 3.6 and the latest version of LLBLGen.

I'm trying to assess what interest there would be for this in the community.

Leave me a comment if you're interested.

Cheers...

Craig

fedge replied on Saturday, November 22, 2008

Hi Craig,

Sounds great/intruiging!  I am not up really to speed with CSLA at the moment apart from a brief look at the sample library/code and reading of the 2005 book, but llblgen is simply magic for round trip db/code/change db/code code gen.  As llblgen now supports LINQ to llblgen, maybe this is in your plan for the future?

I would definetly be interested in hearing more :)

Thanks for your reply,

Matt

swegele replied on Saturday, November 22, 2008

Hi Matt,

You are wise to check first before going down a road with unknown issues.

I have used CSLA for years.  Over a year ago I got an opportunity to apply lessons learned on a custom project.  I generated DAL with LLBLGen.  Sooo nice.  But LLBLGen exposes everything as public and wide open which isn't cool.  Not so nice.

"2 great tastes that taste great together"

My gut said that CSLA would lay nicely over the top of LLBLGen.  I gave it a go.  The LLBLGen DAL is managed privately by the CSLA business object.  It works WONDERFULLY and the code has been running at a federal customer in a multithreaded environment for over a year.  It has:

The trick was how to deal with child objects & serialization in and out of the data portal.  I solved this by always having the Root CSLA object rehydrate it's children after de-serialization.  This was done by marking any child CSLA objects as <nonserializable> etc.  The LLBLGen has the whole relationship tree and the Root CSLA object has the LLBLGen object.  So you always have the ability to build or hydrate a child CSLA object structure.  It turned out to be quite fast and easy.

So on serialization...only the root CSLA object which contains the LLBLGen object goes over the wire.  Then on de-serialization the root CSLA object call a method HydrateChildObjects.

The only other trick was extending the LLBLGen data access class to expose the ability to get connections, transactions, etc from it for use in any custom queries in my CSLA object layer.

Whenever my db changes, I just regenerate my LLBLGen DAL and make appropriate change in my business objects.  I even have had great success with it being used by very beginner developers because it is easy to see what is going on.

The other changes were just lessons learned from using CSLA.

One problem I didn't ever fix was how to hide the DAL dll somehow so a rogue developer (outside party) couldn't just point at it and get unfettered access to the DB bypassing business logic.  But for us this wasn't a risk.  Just would be nice to figure out how to do that someday.

Also this was done circa CSLA 2.5 or so...so this pattern didn't include Rocky's new property syntax.

Maybe this will help you feel confident about moving forward...it worked and is working great for us.  If you need help let me know.

Sean

cds replied on Saturday, November 22, 2008

Hi Sean

Your experience with CSLA over LLBLGen sounds extensive - probably more so than mine. I also found it to be very nice (and if you look back on this thread, I wrote a plug-in to LLBLGen to codegen the CSLA business object classes).

Did you use the self-servicing or the DataAccessAdapter model of LLBLGen?

Craig

fedge replied on Saturday, November 22, 2008

Hi Sean/Craig,

Sean, thanks for the great overview, this all sounds massively promising, and I think this is defintely the right road for me to take further.  I need to do more reading and investigation into the CSLA framework before I can add much value to this discussion, I am especially interested in seeing how the csla silverlight variant fits together!

Sean, did you code up by hand code your CSLA objects?  obviously your knowledge can be used for quality code generation :) which you may already by doing?

Craig, can you post any further notes on the your plug in, its architecture? whether it can be made avialable?

All very interesting, thanks guys,

Matt

 

 

 

 

 

swegele replied on Monday, November 24, 2008

I'll answer both questions here in this reply:

Sean, did you code up by hand code your CSLA objects?  obviously your knowledge can be used for quality code generation :) which you may already by doing?

Good question.  For years we have used CodeSmith to generate our CSLA objects...made our own templates and it was very easy.  I did not update our templates yet to handle the version that lays on top of LLBLGen.  But the amount of code in the CSLA objects is HUGELY reduced given generics.  Good luck on your efforts Matt!  Let me know if I can help you.

Did you use the adapter or self servicing pattern?

We used the adapter pattern for several reasons.  The most important was the need to be able to support some customers with Oracle and others with SQLServer.  I also found it a much easier way to deal with the CSLA layer needing to be in charge of traveling across the wire in a N tier scenario.  In other words...the self servicing pattern might be wanting to hit the db and it isn't there.

Craig, how was your experience having LLBLGen write the CSLA classes for ya?

Sean


Copyright (c) Marimer LLC