Passing Entities accross tiers

Posts   
1  /  2
 
    
brettlj
User
Posts: 27
Joined: 08-Feb-2004
# Posted on: 23-May-2004 04:22:26   

Excellent and much-needed discussion.

jeffreygg wrote:

B: Just set up an extremely lightweight intermediary object for each entity that inherits directly from the LLBGenPro-generated entities and passes all properties, methods, etc directly to the caller - basically don't override any of the members. Also, set up an interface that all of your new inheriting entities implement. This way, the interface your PL/BL objects implement have nothing to do with LLBLGenPro. This keeps your abstraction level high with minimal muss and fuss (although, again, according to Frans this may not be necessary).

I regularly create my own entity classes that inherit from LLBLGen-created entity classes, partly as a way of achieving a degree of abstraction, partly so that I can later add my own properties to an entity that are not persisted in the database.

Your comment on using interfaces implemented by the subclass-entities caught my attention because it is something I've thought about for awhile. Much of the literature I've read seams to suggest that creating interfaces and then programming to them rather than the classes themselves is a good thing. However, I have difficulty seeing the benefit of using interfaces in this situation, especially when I consider the amount of work that would have to go into creating and maintaining an interface for every entity. I fully understand the benefits of using interfaces to sort of simulate multiple inheritance, but struggle to understand the benefits of programming to an interface of an entity class.

Does it really provide more abstraction to do this:


ICustomer cust = CustomerManager.GetSingleCustomer(custId);
txtFirstName.Text = cust.FirstName;

as opposed to this?:


Customer cust = CustomerManager.GetSingleCustomer(custId);
txtFirstName.Text = cust.FirstName;

I would love to be "shown the light" as this is something that has bothered me for awhile... Best, Brett

Fishy avatar
Fishy
User
Posts: 392
Joined: 15-Apr-2004
# Posted on: 23-May-2004 05:57:51   

I think there is a couple of benifits.

First, your forced to create consistant methods/signatures by implementing a common set of interfaces. The stubs will automatically be created for you in vs; which is kinda cool.

Secondly, you can perform polymorphism if your iterate through a collection of entities using your interface variable.

All that said, I've never done it disappointed

My problem I have with inheriting an Entity is... entity's (collections and other Entity types) are not inherited and are therefore not extendable.

Alert: I just went back and read the manual. I guess you can override by setting the EntityFactoryToUse. hmmm, I'll have to look into that a little bit more.

This is one more reason I would like to see a repository of code snippets.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39752
Joined: 17-Aug-2003
# Posted on: 23-May-2004 10:43:30   

brettlj wrote:

Excellent and much-needed discussion. I regularly create my own entity classes that inherit from LLBLGen-created entity classes, partly as a way of achieving a degree of abstraction, partly so that I can later add my own properties to an entity that are not persisted in the database.

This is soon not necessary anymore with the custom includes functionality build in Beta 2 released yesterday simple_smile

Your comment on using interfaces implemented by the subclass-entities caught my attention because it is something I've thought about for awhile. Much of the literature I've read seams to suggest that creating interfaces and then programming to them rather than the classes themselves is a good thing. However, I have difficulty seeing the benefit of using interfaces in this situation, especially when I consider the amount of work that would have to go into creating and maintaining an interface for every entity. I fully understand the benefits of using interfaces to sort of simulate multiple inheritance, but struggle to understand the benefits of programming to an interface of an entity class.

Interfaces are introduced as a tool to, as you already mention, include multiple inheritance, or better: multiple TYPE inheritance. .NET and Java don't support multiple implementation inheritance.

A class also has an interface. This is the reason why I use IEntity and IEntity2 inside the generic code: an entity class in fact implements 2 types: its own type, for example CustomerEntity, and IEntity (or IEntity2). (it implements even more interfaces actually). To see an object as an instance of a given type, IEntity, CustomerEntity, ISerializable, EntityBase etc., use a reference variable of that type and give that variable a reference to the object.

Does it really provide more abstraction to do this:


ICustomer cust = CustomerManager.GetSingleCustomer(custId);
txtFirstName.Text = cust.FirstName;

as opposed to this?:


Customer cust = CustomerManager.GetSingleCustomer(custId);
txtFirstName.Text = cust.FirstName;

That depends on how you defined 'Customer'. If that's a derived class from a generated entity class, 'Customer' exposes a much bigger set of members than ICustomer, which for example only exposes the bare properties and 1 or 2 methods.

@Fishy: Code snippets are often very database specific. I think theory is more important than a snippet of a sales order class with entities and relations that are not matching your database, or do you see this differently?

Frans Bouma | Lead developer LLBLGen Pro
Fishy avatar
Fishy
User
Posts: 392
Joined: 15-Apr-2004
# Posted on: 23-May-2004 17:36:41   

It helps me to see theory and code together. Perhaps more examples using the Northwind data base. Especialy with the new features that you have just introduced.

Thanks,

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39752
Joined: 17-Aug-2003
# Posted on: 23-May-2004 20:12:03   

Fishy wrote:

It helps me to see theory and code together. Perhaps more examples using the Northwind data base. Especialy with the new features that you have just introduced.

Which features are you particular interested in seeing better documented?

Frans Bouma | Lead developer LLBLGen Pro
Fishy avatar
Fishy
User
Posts: 392
Joined: 15-Apr-2004
# Posted on: 24-May-2004 04:19:24   

One of the things I would normally do is write sprocs for CRUDs to support audit trails. So, examples of overriding the OnSave method would be a start.

Another would be examples of extending properties and methods for entities and entity collections.

Another would be examples of customizing the generator. Like creating a lightweight arraylist of the elements of a table. Or, creating a View that allows updates disappointed

Also, examples of what other llblgen fans are doing. sunglasses

I'm just throwing it out there. The forums and your quick response handles most every problem we come up with, so it's not a big deal. simple_smile

Take care,

Posts: 497
Joined: 08-Apr-2004
# Posted on: 25-May-2004 11:14:42   

brettlj wrote:

I regularly create my own entity classes that inherit from LLBLGen-created entity classes, partly as a way of achieving a degree of abstraction, partly so that I can later add my own properties to an entity that are not persisted in the database.

Is this a common practice for LLBLGen users? I toyed with the idea of inheriting from the LLBLGen entities, in order to add extra properties (and simple methods in some cases). In the end I modified the "template" file so that for each entity that is generated, it also generates a really simple entity, that contains the properties (fields) for the table. Heres an example:


public class System_AreaCustEntity
{
    private System.String _AreaCode;
    private System.String _Parent_AreaCode;
    private System.Int32 _Sequence_No;
    

    /// <summary>
    /// The AreaCode property of the Entity System_Area
    /// </summary>
    public virtual System.String AreaCode
    {
        get
        {
            return (System.String) _AreaCode;
        }
        set
        {
            _AreaCode = value;
        }
    }
              ....rest of properties...
}

I then use some simple code to populate a "custom entity" from a LLBLGen entity, and pass this back up to the PL layer from the BLL layer.

The reasons I decided to do this were:

  • Extensibility: I can modify my custom entity to ingerit from a base entity class
  • Abstraction: My custom entity can be passed around, its consumers don't need to know about LLBLGen
  • Purity: I like the way it only exposes the bare properties of the table. I can hide all those properties of the LLBLGen class that I don't want.

I haven't done anything like this before, this is my first major .NET project so I am in no way suggesting I am right. Can anyone think of any obvious flaws in this, and reasons that I should change this to instead derive from LLBLGen entities?

Muchos Gratis!

wayne avatar
wayne
User
Posts: 611
Joined: 07-Apr-2004
# Posted on: 25-May-2004 11:31:36   

Hi MattWoberts

I think this

In the end I modified the "template" file so that for each entity that is generated, it also generates a really simple entity,

is a great idea.simple_smile

If you look back at the previosue examples that we discussed on page 1.

EmpMan.EmployeeRecord.Property1 = Value1 EmpMan.EmployeeRecord.Property2 = Value2 EmpMan.EmployeeRecord.Save()

EmployeeRecord is basicaly an custom entity contain in a manager. I know that you are passing custom entities around - so i think the way you are going about this is the right way. Sounds logical.

brettlj wrote:

I regularly create my own entity classes that inherit from LLBLGen-created entity classes, partly as a way of achieving a degree of abstraction, partly so that I can later add my own properties to an entity that are not persisted in the database.

Is this a common practice for LLBLGen users?

I covered this as option 2 in my first reply to you on the previouse page.wink

I haven't done anything like this before, this is my first major .NET project so I am in no way suggesting I am right. Can anyone think of any obvious flaws in this, and reasons that I should change this to instead derive from LLBLGen entities?

This type of framework design is not limited to LLBLGen users - It is common practise. I don't know how much you know about design patterns - But i think you should get a book on it - It is great even for just getting ideas for what is possible and what is the correct \ preferd way.

Wayne

Posts: 497
Joined: 08-Apr-2004
# Posted on: 25-May-2004 13:03:05   

Thanks Wayne simple_smile

I think I must be coming full circle with some of my questions - apologies for that. I keep reading diferent articles re: architecture which force me to rethink my orginal design.

On the subject of books - I have the Fowler book on order from amazon, so I should soon be a master of patterns wink

IowaDave
User
Posts: 83
Joined: 02-Jun-2004
# Posted on: 03-Jun-2004 17:37:12   

I've been spending some time considering the options for separating the PL from LLBLGen in the BLL. This forum has been very helpful. Before I get there, I have a couple other related questions.

  1. A very basic question I have is - the doc says to use Adaptor templates when using remoting (which I assume includes web services?). Yet Wayne is going over the wire with self servicing.
  2. Another newbie question I have about the dataadaptor templates - are they actually using an ADO.Net DataAdapter? The reason I ask is my boss is opposed to using DataAdapter for performance reasons.

Dave

wayne avatar
wayne
User
Posts: 611
Joined: 07-Apr-2004
# Posted on: 03-Jun-2004 21:31:09   

Hi

Yet Wayne is going over the wire with self servicing

I received this request from the client after we started with self servicing - I spent some time discussing remoting with devildog but haven't actually started to implement this yet. This is propably still about a year away.

As far as i can see - should self serving not be a problem with remoting as my BL is not passing LLBLGen entities around. So it is not really FAT Structures being passed around.

If i remember correctly LLBLGen entities can not be used directly with Webservices either. So a BL that acts as an complete abstraction layer seperating the PL from DL is very important especialy if you want to add things like remoting and webservices in the future.

Remember Add-ons like Webservices and remoting get's build ontop of the BL NOT the DL.

_Almost like a Car confused - The Operator Interfaces with the Steering wheel (PL) it then interfaces with the Steering Column (BL) that in turns interfaces with the Steering Rack and wheels(DL). - Examples everywhere!wink _

As soon as you need to add an LLBLGen uses \ imports clause in your PL you must know that there is a problem with your design and you are not acheiving total abstraction. (_No Steering Rack in the cockpit, Pleasewink stuck_out_tongue_winking_eye _) See message posted by me on Posted on: 21-May-2004 10:58:08 at http://www.llblgen.com/TinyForum/Messages.aspx?ThreadID=802 about DL in the PL.

I am busy with a example on how to implement a BL with LLBLGen(using Self Servicing C# and SQLServer) - Because i had so many requests for it. - Should be done by the weekend - Maybe Otis will stick it onto the 3rd Party section - If we ask him nicely. I am not adding Webservices and remoting to it. - That part you have to figure out yourselfsstuck_out_tongue_winking_eye

Devildog74
User
Posts: 719
Joined: 04-Feb-2004
# Posted on: 04-Jun-2004 03:08:14   

IowaDave wrote:

I've been spending some time considering the options for separating the PL from LLBLGen in the BLL. This forum has been very helpful. Before I get there, I have a couple other related questions.

  1. A very basic question I have is - the doc says to use Adaptor templates when using remoting (which I assume includes web services?). Yet Wayne is going over the wire with self servicing.
  2. Another newbie question I have about the dataadaptor templates - are they actually using an ADO.Net DataAdapter? The reason I ask is my boss is opposed to using DataAdapter for performance reasons.

Dave

  1. The reason the Adapter pattern fits with remoting better, is because the CRUD operations are abstracted and hidden from the presentation layer. If you read ingo rammer's bood on advanced remoting he points out how to interact with remote objects via an interface, and he stresses the importance of hiding the implementation on the server side. Otherwise, what is the point of a distributed application.

  2. They use ADO.NET I beleive. But they are not the traditional Microsft SQL Data Adapter or OLE DB Data Adapter objects that you think of.

If he is worried about speed, I can write you some speed tests that you can run and bench mark using NUnit. When I was first evaluating LLBLGen, I was a firm beleiver of everthing being stored procs due to pre compiled execution plans and cached stats. So I created some tests using the DB Hammer database, which is about 10 million credit card transactions in one table. I executed 5 different queries 10,000 times in SQL Server Query Analyzer and performed the same test using LLBLGen. LLBLGen took about 1 second longer per guery because a connection was created and destroyed for each execution, where as with Query analyzer, only one connection was made. The execution plans were virtually identical between LLBLgen and Query Analyzer. So, IMHO, LLBLGen wins, because your get so much more for a negligable performance hit.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39752
Joined: 17-Aug-2003
# Posted on: 04-Jun-2004 08:25:24   

The connection creation delay is only the first time though. Every next time a connection is made there is hardly a delay due to connection pooling simple_smile

Frans Bouma | Lead developer LLBLGen Pro
wayne avatar
wayne
User
Posts: 611
Joined: 07-Apr-2004
# Posted on: 09-Jun-2004 10:02:50   

Hi All

The question stated by 'IowaDave' worries me....

Yet Wayne is going over the wire with self servicing.

Please look at my responses to 'IowaDave'. Am i missing something because i have seen several postings about self servicing not to be used in N-Tier enviroment?confused

netLearner
User
Posts: 150
Joined: 18-Oct-2003
# Posted on: 09-Jun-2004 18:01:16   

wayne wrote:

Hi All

Please look at my responses to 'IowaDave'. Am i missing something because i have seen several postings about self servicing not to be used in N-Tier enviroment?confused

Is this really true? If so can anyone explain why we should not use Self servicing for N-tier environment.

Thanks.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39752
Joined: 17-Aug-2003
# Posted on: 09-Jun-2004 18:11:31   

Both template sets can be used in a variety of scenario's. SelfServicing and Adapter both can be used in n-tier development, just because for n-tier development you'll define the rules yourself.

A result of this is that if you want your GUI developers not to be able to call Save() methods on entities received from the BL classes, you can't use SelfServicing, you have to use Adapter. If you don't care about such rules, SelfServicing is fine. simple_smile For a lot of applications this is the case, as perhaps the developer writing the BL classes is also writing parts of the GUI, or the team isn't that large.

SelfServicing is not recommended in a remoting scenario, that's about the only scenario SelfServicing is not that suitable for.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39752
Joined: 17-Aug-2003
# Posted on: 09-Jun-2004 18:18:54   

IowaDave wrote:

I've been spending some time considering the options for separating the PL from LLBLGen in the BLL. This forum has been very helpful. Before I get there, I have a couple other related questions.

  1. A very basic question I have is - the doc says to use Adaptor templates when using remoting (which I assume includes web services?). Yet Wayne is going over the wire with self servicing.

You can use SelfServicing in remoting scenario's, it's fully functional. The reason not to use SelfServicing in a remoting scenario is very simple: load on demand code and for example Save() methods do not work on the client, as the database is on the server. If you control both client and server, you can work around this in selfservicing. However if you have a team working on the client and a team working on the server, it's more wise to use Adapter, as the client team can't call any persistence code nor can it accidentily call a load-on-demand enabled property.

  1. Another newbie question I have about the dataadaptor templates - are they actually using an ADO.Net DataAdapter? The reason I ask is my boss is opposed to using DataAdapter for performance reasons.

No, only for fetching typed lists and typed views, which are derived from datatables and fetching these is more efficient by calling a dataadapter's Fill method. All entity persistence code works with datareaders for fetching and ExecuteNonQuery calls for saving/deletes.

'Adapter' 's name is coming from the idea that you use an 'adapter' to execute persistence logic like fetching data or saving data. You can have different adapters (for example for different databases) which you use in your application, so you use the 'adapter' to talk to the database of choice.

Frans Bouma | Lead developer LLBLGen Pro
IowaDave
User
Posts: 83
Joined: 02-Jun-2004
# Posted on: 28-Jun-2004 17:41:44   

A question for those using custom entities and passing them across tiers. Are any of you using web services? If so, how are you replacing the xmlRead and xmlWrite methods that are part of llblgen? Did you duplicate these methods, and if so, how do you handle all the flags, etc that get set in the llblgen'd entity class? From what I've read on the forum, those using the custom entity classes are just passing the custom classes' properties around. Don't we need the flags and other fields that llblgen would set, when we deserialize the soap message into a llblgen entity?

Pardon me if this has been answered elsewhere. Thanks for any feedback.

I wonder now that maybe nobody else is using web services as their solution?

alexdresko
User
Posts: 336
Joined: 08-Jun-2004
# Posted on: 30-Jun-2004 17:33:35   

Cadmium wrote:

I disagree. The entities llblgenerates are about as generic as you can ge......

I agree with your disagreement. It should not be difficult at all to replace LLBLGen with another good O/R mapper.

1  /  2