Did someone ever think of this ...

Did someone ever think of this ...

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


manulisa posted on Thursday, April 10, 2008

Hi all !

First of all i'm a big fan of CSLA ! But there's one thing which bothers me ... notably : what is the data access code # Data Region # doing in the business object. This should be separate classes only known in the DAL Layer, one for each BO, like this  (i take customer object as example):

Business Layer :

Customer.cs (contains properties, methods, validation, authorization, factory methods)

DataAccesslayer:

CustomerDataService.cs (contains the DataPortal_XYZ methods for DataRetrieval).

Why ? For sake of abstraction of course : then in large teams business developpers are abstracted from the specific Data Access Layer and dedicated DAL programmers can write there Data Access Code in separate code-block.

From the current implementation, this isn't possible, as all code resides in the object it self, just separated by some region identifier ....

Of course there should be some adaptions on the CSLA framework to make this work i guess ...

Anyone had the same feeling ?

 

Thx for any response.

 

manulisa.

 

 

 

skagen00 replied on Thursday, April 10, 2008

You know, no one has ever brought up this subject before! ;)

Rocky discusses this in his book - the idea of keeping business logic separate from the data access logic is largely achieved by having well defined methods where you put your data access code. You simply don't put data access code outside of the DataPortal methods and the methods that they call.

There are various threads if you do a search which talk about trying to abstract away the data access. The discussion including DeepData that was recently asked about (look for a recent thread looking for the video on this) includes a link to the DeepData discussion (among other subjects).

So yes it can be done and yes people have discussed it before. Me, I'm perfectly content keeping my data access in the same classes as the business logic provided they were well segmented into well defined areas of the code.

triplea replied on Thursday, April 10, 2008

I prefer the DA code within my object too. You could of course use a partial class for aesthetic and/or code gen reasons but thats probably as far as I would go...

andrewem replied on Wednesday, May 07, 2008

Hi,

Did you ever get a response to this question? I have the exact same question. I don't understand how something so blatently obvious is not addressed formally. I understand that Rocky is a Microsoft Regional Director, but, we have very large clients that use Oracle (when I say large, I mean cities). They are not going to switch to SQL Server just to use our application. So it is important that this is addressed formally.

A

skagen00 replied on Wednesday, May 07, 2008

CSLA is designed to give you a framework to architect your business objects. There is place where you put whatever data access code you want in order to do CRUD for your business objects. Whether you do that code using DTOs, without DTOs, with SQL Server, to XML files, with Oracle -- that's all up to you.

What do you mean by addressing formally? I'm not sure I understand your question.

andrewem replied on Wednesday, May 07, 2008

Hi,

We'll lets say your application supports three DBMSs: SQL Server, Oracle, and MySql.

Are you suggesting that all of the code for these three different DBMSs must be placed into your one business object?

I was asking if anyone has a simple answer that says yes, they all go in there or no, you can have a pluggable architecture so you don't have to embed everything into your business objects.

A

JoeFallon1 replied on Thursday, May 08, 2008

andrewem:

We'll lets say your application supports three DBMSs: SQL Server, Oracle, and MySql.

Are you suggesting that all of the code for these three different DBMSs must be placed into your one business object?

I was asking if anyone has a simple answer that says yes, they all go in there or no, you can have a pluggable architecture so you don't have to embed everything into your business objects.

This is the 3rd thread you asked this question. It has already been answered twice.

See: http://forums.lhotka.net/forums/thread/23394.aspx for my response.

Joe

 

smiley riley replied on Monday, May 12, 2008

Yes you can have a 'pluggable architecture so you don't have to embed everything into your business objects', but from what I have seen do not use CSLA.

RockfordLhotka replied on Monday, May 12, 2008

smiley riley:
Yes you can have a 'pluggable architecture so you don't have to embed everything into your business objects', but from what I have seen do not use CSLA.

CSLA is intentionally neutral on data access. This is to say that CSLA does not care how you get at your data.

The assumption is that the people using CSLA are intelligent professionals who can make good decisions that best fit their application's needs. That they can balance performance, coupling, complexity and various other factors to come up with a solution that meets their needs.

It sounds, on the whole, like you are looking for something more prescriptive and thus less flexible. For a framework that takes control away from you and makes more choices for you. That's fine, but that's not the purpose of CSLA so much.

Yes, parts of CSLA are very prescriptive. But when it comes to interacting with the UI and with data storage CSLA is very intentionally neutral and flexible.

So it is absolutely possible to use a pluggable architecture. In fact there are several different ways you might construct such a pluggable architecture - all of which work with CSLA. Or you might choose the simpler, faster technique of putting the data code in the DP_XYZ methods. Or you might choose to use a DTO-based data layer (as per one of your comments in another thread).

The point here, is that I've tried to make CSLA as flexible as I can in this regard, so each user of CSLA can apply their own intelligence and skills and experience to make the best overall solution to meet their particular requirements.

smiley riley replied on Monday, May 12, 2008

RockfordLhotka:

smiley riley:
Yes you can have a 'pluggable architecture so you don't have to embed everything into your business objects', but from what I have seen do not use CSLA.

CSLA is intentionally neutral on data access. This is to say that CSLA does not care how you get at your data.

The assumption is that the people using CSLA are intelligent professionals who can make good decisions that best fit their application's needs. That they can balance performance, coupling, complexity and various other factors to come up with a solution that meets their needs.

It sounds, on the whole, like you are looking for something more prescriptive and thus less flexible. For a framework that takes control away from you and makes more choices for you. That's fine, but that's not the purpose of CSLA so much.

Yes, parts of CSLA are very prescriptive. But when it comes to interacting with the UI and with data storage CSLA is very intentionally neutral and flexible.

So it is absolutely possible to use a pluggable architecture. In fact there are several different ways you might construct such a pluggable architecture - all of which work with CSLA. Or you might choose the simpler, faster technique of putting the data code in the DP_XYZ methods. Or you might choose to use a DTO-based data layer (as per one of your comments in another thread).

The point here, is that I've tried to make CSLA as flexible as I can in this regard, so each user of CSLA can apply their own intelligence and skills and experience to make the best overall solution to meet their particular requirements.

Sorry, It probably looks like i have come on here to bad mouth all your good work, which is not the case. Its a subject that interests me and I like thinking about new ideas.

Very interesting, because that was not how I percieved csla. Just shows how wrong you can be. ;-) I saw it more as a framework to try to constrain developers in re-use and not re-creating the wheel everytime a new project came along.

I think I probably need to approach CSLA at a time with fresh eyes where I have not had anothers implementation tint my spectacles as it were.

I think this is very apt, and probably one of the hardest things to do. 

'balance performance, coupling, complexity'

RockfordLhotka replied on Tuesday, May 13, 2008

smiley riley:

I think this is very apt, and probably one of the hardest things to do. 

'balance performance, coupling, complexity'

There's no doubt that achieving balance is very hard.

It is certainly true that parts of CSLA are very prescriptive. The framework is focused on helping you build a domain business layer, and within that context it is reasonably prescriptive. It specifies the structure of each object stereotype, and how various stereotypes interact with each other. It specifies how you implement properties, validation rules, business rules and authorization rules. It specifies how you are allowed to move objects between client and app server (mobile objects).

But it expressly does not specify how you create the UI or other interface. It enables data binding in Windows, Web and WPF, but doesn't require it.

And it expressly does not specify how you talk to the database or other data store. It specifies the control points for data operations (the DataPortal_XYZ methods), but doesn't specify how you write them, or what technologies you use.

mr_lasseter replied on Wednesday, May 07, 2008

Have you seen this? There are examples of using dtos between the business layer and data access layer.  In the Data Access Layer you can pull the data from anywhere you want...

http://www.lhotka.net/Article.aspx?area=4&id=7fbb619a-ba81-4157-b434-8756b68ccbd0

andrewem replied on Wednesday, May 07, 2008

Hi,

We've looked at that, but our existing methodology is must cleaner. We were hoping to use inheritance and just implement the data access methods in another assembly. That's what we are doing now and it works. But we are looking to use something that more closely ressembles the book, but it seems like nothing has been established as the best method yet.

Thanks for your help.

A

mr_lasseter replied on Wednesday, May 07, 2008

Using dtos you have much better separation of concerns, you can make any changes directly to your  data access layer without ever having to touch your business object layer directly.  As opposed to the inheritance, where changes in the superclass could have a direct effect to  its subclasses.

In my application I acutally went a different route. I did all the database code in the data portals like normal, but I programmed interfaces rather than the acutal implementations.  So my implementation looks like the following:

private void DataPortal_Fetch(ByIdCriteria criteria)
{
   
    const string sp = "gsp_IN_PagerView_GetById";
    using (BaseConnection cn = ConnectionFactory.GetConnection(Database.ConnectionName))    
    using (IDbCommand cm = cn.GetCommand(sp, CommandType.StoredProcedure))
    {
        cn.AddParameter(cm, "a_id", DbType.Int32, criteria.Id);
        
        using (SafeDataReader dr = new SafeDataReader(cm.ExecuteReader()))
        {
            LoadData(dr);
        }
    }
            
}

The ConnectionFactory takes care of creating the correct connection and command types, which is determined from reading the config file.  The business object knows nothing about what backend database is being used.  The problem with this is the data must come from a database.  With the dtos the information could come from anywhere (Web Services, XML Files, etc).  I think in the long run dtos give you much better separation of concerns and cleaner code in data portal.  The code below looks much cleaner, IMO.


private void DataPortal_Fetch(ByIdCriteria criteria)
{    
    DtoDepartment departmentDto = DepartmentsRepository.GetDepartment(criteria.Id);
    LoadData(departmentDto);                
}
 

RockfordLhotka replied on Wednesday, May 07, 2008

You can look at the CSLA .NET 3.5 ProjectTracker code - it uses an external DAL created using LINQ to SQL. The model itself doesn't allow for swapping out different DAL implementations, but it is a relatively small step to get there. I am hopeful that ADO.NET EF will allow a similar implementation where you don't need to worry about swapping out the DAL at the DataPortal_XYZ level, because EF will better encapsulate the solution - time will tell.

In terms of getting the business object's fields loaded with data, there are many options. ProjectTracker 3.5 uses a model not unlike previous versions, and quite similar to the DeepData example on my web site.

Or you can use partial classes (especially if you create separate projects for your client and server assemblies - using Visual Studio's linked file capability to share the actual core code files). Or you can use an inheritance model to do the same basic thing. Or you can use an interface-based model. Or you can use reflection. There are many options.

One thing I'm doing in my CSLA Light prototype is allowing the business object to specify that the data portal should call a "factory object" rather than creating/initializing the business object directly. You specify the factory object type, and you must implement a factory object for each root business type.

The model is required for CSLA Light, because you can't necessarily trust the Silverlight client (I don't think) and so there is a need for the business developer to get deeper into the middle of the data portal processing. Obviously this requires more coding, because the data portal is doing less work, but that's the tradeoff.

When doing this with the CSLA Light data portal you'll typically have your factory simply call the real business object's static factory methods:

[MobileFactory("MyDll.CustomerFactory,MyDll", "Create", "Load")]
public class Customer : BusinessBase<Customer>
{ ... }

public class CustomerFactory
{
  public Customer Create()
  {
    // make sure Silverlight caller is allowed to do this
    return Customer.NewCustomer();
  }

  public Customer Load(SingleCriteria<Customer, int> criteria)
  {
    // make sure Silverlight caller is allowed to do this
    return Customer.GetCustomer(criteria.Value);
  }
}

I might implement something similar for the .NET data portal too. It would require more work on the business developer's part though, because the .NET factory (unlike the Silverlight one) would have to do everything the data portal does today:

  1. Create an instance of the object (probably using Activator.CreateInstance())
  2. Trigger the data load or initialization or delete or update or insert
  3. Call MarkNew() or MarkOld() as appropriate
  4. Call the pre- and post- operation methods if you care (like the DataPortal_OnDataPortalComplete)

Luckily CSLA .NET 3.5 exposes the same helpers in Csla.Reflection that are used by the data portal itself (including all the cool dynamic method invocation and caching stuff), so you really can replicate what SimpleDataPortal does for you just the way it is done by CSLA - or you can invent your own scheme as long as the result is the same.

I'm not entirely sure I'll go down this road for .NET. For Silverlight it is very important. For .NET it mostly provides a very complicated alternative where people can really mess up the data portal if they do it wrong. On the upside though, it offers some pretty impressive flexibility in terms of invoking various advanced types of DAL.

It might help you, because your factory would be able to create an instance of a subclass of the real object - the subclass that implements the data access logic and loads the protected fields. That might look something like this:

[DataFactory("MyDataDll.CustomerFactory,MyDataDll", "Create", "Load")]
public class Customer : BusinessBase<Customer>
{ ... }

public class CustomerDal : Customer
{ ... }

public class CustomerFactory
{
  public Customer Create()
  {
    var cust = new CustomerDal();
    cust.LoadWithDefaults();
    return cust;
  }

  public Customer Load(SingleCriteria<Customer, int> criteria)
  {
    var cust = new CustomerDal();
    cust.LoadWithData(criteria.Value);
    return cust;
  }
}

Presumably LoadWithDefaults() and LoadWithData() would not only load the object's fields, but would call MarkNew() or MarkOld() as appropriate.

I don't know if this would cause issues with serialization - though I suspect it probably would. The serializers would serialize a type of CustomerDal and be unable to serialize it back into something called Customer on the caller - so now that I think about this, it really won't work unless CustomerDal implements ISerializable and in that implementation tells the serializer to deserialize into a different type (Customer in this case). That's pretty complex code to expect a business developer to write into every DAL class - so I'm liking this option less and less the more I think about it...

smiley riley replied on Monday, May 12, 2008

Yes, and Im moving it all after taking over someones code.

To me its unmanageable, and causes coupling issues.

 

I have to add it could just be the way the code I inherited has been written.

Copyright (c) Marimer LLC