Suggestion For LLBL

Posts   
 
    
psandler
User
Posts: 540
Joined: 22-Feb-2005
# Posted on: 20-Apr-2005 01:15:57   

I have a suggestion for LLBL that might be possible, and might not be. This sort of relates to the question/thread I posted here:

http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=2400

Basically, I'm using a Business Layer that is abstracted away from LLBL Gen. My BL has no knowledge of the LLBL assemblies. I am aware of the arguments against worrying about vendor-lock, and tend to agree with many of them. However, this is a client/project requirement and we can't get away from it.

We use a sort of "mapping" layer (call it the ML) to convert domain objects to DAL (LLBL) objects. The ML is completely stateless, and once a BL object is passed to the ML for saving, there is no additional interaction with the interface (just a return value, indicating success/failure).

Retrieving from the database and populating a BL object are a snap. Because adapter entities are abstracted away from the actual data-adapter, it's very easy to write static mapping methods that are re-usable. Saving a "base" object is also very straightforward.

Where it becomes tricky is when we need to save a collection of BL objects that can contain collections of other BL objects. Frans pointed me in the right direction in the thread linked above. What we end up doing is putting our BL collection in a hashtable and calling a BL-to-DAL comparison utility to add/remove/delete entities from the DAL collection.

This does work. However, I have not yet written the code to cover every possible type of collection save I will need to support for this project:

MergeSave (save all collection members, except those that already exist, which are updated) CompleteSave (save all new collection members, delete all that don't exist, update those that exist) RelationSave (save new relations, delete ones that don’t exist, leave existing ones with no update) RelationMergeSave (etc.)

What I was wondering is if it would be possible to natively support these (and other) different types of collection saves in future versions (including collections that are part of a recursive save). This would allow abstracted BL layers to interact more easily with DAL objects--they would be no more difficult than retrieval mappings. All you would have to do is populate a DAL/LLBL object (as deep as you want to save it), then call whichever type of save you wanted to perform. The save logic would fetch a parallel object graph and do the comparison for you.

There are probably more scenarios than I am thinking of, and I am NOT (even for a second) suggesting that this would be easy. But I think it would meet a requirement that people like me run into fairly often: "no vendor lock". I also think, in general, that even outside the vendor lock issue there are instances where hiding your data access strategy is important or required, either by a client or by the nature of the project (hosting public web services might be one example).

Again, I’m not claiming that this would be easy (maybe it’s not even possible). Perhaps this is something other people have already encountered and resolved, and might share some code?

I have selfish reasons for wanting this type of support, of course. smile But I also think it would be good for the product (which I love, if that’s not clear already simple_smile ).

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 20-Apr-2005 11:29:12   

I can be short on the subject of vendor lock-in: there always is a vendor lock-in. Not by the entity class usage but by the fact that you have to formulate filters using a given syntaxis and that you have to use some sort of persistence logic to get the data manipulated in the database. On .NET there is no standard for this when it comes to O/R mapping.

To abstract away a data-access scenario, two things are done: 1) the data container classes (entity classes) are re-written and some copy logic is added to move the data into entity classes and vice versa 2) a facade layer is placed on top of the DAL to hide the real persistence logic access and the filter construction.

With 1) you lose functionality build in the entity classes, like databinding, fk syncing etc. with 2) you have to find a way to formulate filters/data-access logic outside the facade tier and you thereby lose functionality like the unitofwork classes.

As a solution out of the box for the facade tier is also a vendor lock-in, it's not possible to provide such a tier. I've toyed with the fact to add a layer for POCO objects (plain old clr objects) and a normal o/r mapper session object which uses an xml mapping file etc., but that would not help much, as the vendor lock-in is still there plus the POCO objects are pretty useless, they lack databinding support, version tracking etc. and using them in a disconnected manner is pretty hard.

The discussion about vendor lock-in is pretty moot. It's the same as with stored procedures vs. dyn. sql: the arguments are stupid. If vendor lock-in is a problem, do you use any 3rd party GUI controls? If so, ever tried to migrate your code from one GUI control package to another one? I can tell you, it takes a lot of time, and especially if the application is huge.

I know you care and I appreciate your effort in explaining what you want for a feature, but I think helping you in this will not solve the real problem, if there is any. (I find the whole 'vendor locking' problem pretty meaningless, as it exists everywhere but it's apparently only a real problem when it comes to data-access...). The real vendor-specific items are still there and giving a solution for that is not giving a real solution, just another way of doing the same thing, and provided by just one vendor.

The only thing that would solve this vendor lock-in discussion once and for all is in the situation where MS defines a standard like EJB or similar, though even then, it's not that simple, as for example in the java world more and more people move away from EJB and simply go for hibernate as it is the defacto standard.

Frans Bouma | Lead developer LLBLGen Pro
psandler
User
Posts: 540
Joined: 22-Feb-2005
# Posted on: 20-Apr-2005 17:07:09   

A thought-provoking response that may take me some time to digest. simple_smile

If I may pose two follow-up questions:

  1. If you were in my/our shoes, and HAD to have this facade/mapping layer while using LLBL only as a data access, would you take the approach I mentioned in my original post? Write generic functions to map BL collections to DAL collections? Do you see any other approach?

  2. You mentioned hibernate in your response. Do you feel that hibernate has the exact same issues as it applies to vendor-lock? I don't know much about hibernate, but it seems to me that it's an easier pill to swallow when you create your own BL and then map it to a vendor specific tool. It's a fine point, but it's exactly the kind of argument you end up having with other developers, the client, or the project manager.

EDIT: Note on #2--I'm not saying I agree with this point, it's just what I hear when these discussions come up. I wanted to make that more clear. simple_smile

One great compliment I think you can take away from this thread is that LLBL is an amazing tool even if you DON'T use it as a business layer. simple_smile

Answer
User
Posts: 363
Joined: 28-Jun-2004
# Posted on: 20-Apr-2005 21:07:56   

As a solution out of the box for the facade tier is also a vendor lock-in, it's not possible to provide such a tier. I've toyed with the fact to add a layer for POCO objects (plain old clr objects) and a normal o/r mapper session object which uses an xml mapping file etc., but that would not help much, as the vendor lock-in is still there plus the POCO objects are pretty useless, they lack databinding support, version tracking etc. and using them in a disconnected manner is pretty hard.

I think that would be a pretty cool feature. Espescially if you didnt want 3rd parties using the llblgen entities. Even a converter to use datasets would be sweet wink

But i think it would allow customers to create a true domain model if they wanted. rather then each entity being based off a table. But still be able to use there favorite tool. But like you mentioned, versioning and stuff would be a pain, you would have to give up features in order to use the plain old clr objects.

Speaking of this, if i remember correctly, when i firsst bought llblgen about a year ago, i remember you mentioning something about being able to design the objects in the Designer and having it generate the DAL code and entities for you. Is this what you were referring to?

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 21-Apr-2005 10:14:38   

psandler wrote:

A thought-provoking response that may take me some time to digest. simple_smile

If I may pose two follow-up questions:

  1. If you were in my/our shoes, and HAD to have this facade/mapping layer while using LLBL only as a data access, would you take the approach I mentioned in my original post? Write generic functions to map BL collections to DAL collections? Do you see any other approach?

No, I wouldn't take that approach. My reasoning is that there is an X amount of work to be done. You use a given tool, in this case LLBLGen Pro to decrease that amount of work with, say, 30%. And then you increase the work again with an unknown factor without adding any (IMHO) real value simple_smile . IMHO that's not the best way you can do things.

Now, with a bit of code generation, you can get very far in this though, so I'd suggest that IF you want to do this, look into code generation FIRST. See how you can create your own collection templates which generate generic classes and work with the generated llblgen pro classes, but I can assure you, you'll do a lot of the work again that's already be done for you simple_smile . Life's complicated enough wink

  1. You mentioned hibernate in your response. Do you feel that hibernate has the exact same issues as it applies to vendor-lock? I don't know much about hibernate, but it seems to me that it's an easier pill to swallow when you create your own BL and then map it to a vendor specific tool. It's a fine point, but it's exactly the kind of argument you end up having with other developers, the client, or the project manager.

Hibernate is a java O/R mapper, and has about 50% of the market. I.o.w.: what they do is what others will do after them. In Java there are a couple of standards, one of them is EJB-CMP. Which means in short that you have a container and the container takes care of the persistence for you, and every O/R mapper obeys the standards set for that EJB-CMP framework.

Though, in the last 2 years or so, more and more people hate the EJB framework and use vendor specific options, like JBoss with Hibernate or Tomcat with another specific framework. That's all ok, the real vendor lock-in comes from the query language used. If your application has a lot of filters defined in HQL (the query language of hibernate) then you can't use these filters with Toplink (Oracle's O/R mapper) and vice versa.

So at some point, there is always a vendor lock-in. But in a way, it's already there with .NET: if in a few years time, Java seems to be the better option, your app might be hard to port to Java. So when you write an application, you have to accept there is vendor lock-in.

I do understand that vendor lock-in with LLBLGen Pro can be a problem for some organisations. That's also why every customer gets the full sourcecode for the code generators, the runtime libraries and the database drivers. This means that they can adjust the code generator as they please and generate code how they want it, even modify the runtime libs if they want to. Because, vendor lock-in is fine, as long as you don't get trapped by it. Like MS has us all trapped with VS.NET 2003. We can't switch to an alternative because they all (still) suck and we thus eagerly await for v2005 and we're probably very willing to shell out money for it.

EDIT: Note on #2--I'm not saying I agree with this point, it's just what I hear when these discussions come up. I wanted to make that more clear. simple_smile

No problem, it's good to share these thoughts, as they are a concern for you and thus a for us something to solve simple_smile

One great compliment I think you can take away from this thread is that LLBL is an amazing tool even if you DON'T use it as a business layer. simple_smile

Thanks! smile

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 21-Apr-2005 10:18:57   

Answer wrote:

As a solution out of the box for the facade tier is also a vendor lock-in, it's not possible to provide such a tier. I've toyed with the fact to add a layer for POCO objects (plain old clr objects) and a normal o/r mapper session object which uses an xml mapping file etc., but that would not help much, as the vendor lock-in is still there plus the POCO objects are pretty useless, they lack databinding support, version tracking etc. and using them in a disconnected manner is pretty hard.

I think that would be a pretty cool feature. Espescially if you didnt want 3rd parties using the llblgen entities. Even a converter to use datasets would be sweet wink

You'd think? simple_smile . Well, the converter to/from datasets might be an option for v2.0, I don't know. .NET 2.0 and vs.net 2005 is build around .xsd's so I have to build in code which converts types to xsd's anyway, which means that with an xsd you can produce datasets and back.

But i think it would allow customers to create a true domain model if they wanted. rather then each entity being based off a table. But still be able to use there favorite tool. But like you mentioned, versioning and stuff would be a pain, you would have to give up features in order to use the plain old clr objects.

Correct. There are a couple of O/R mapper frameworks for .NET on the market which focus on this. they all have the same problem: databinding support sucks and working disconnected is a pain.

Speaking of this, if i remember correctly, when i firsst bought llblgen about a year ago, i remember you mentioning something about being able to design the objects in the Designer and having it generate the DAL code and entities for you. Is this what you were referring to?

Yes, I didn't have enough time to build it into 1.0.2004.2, but it will come in 1.0.2005.1, in june, which will sport a full entity editor with inheritance and more simple_smile .

Frans Bouma | Lead developer LLBLGen Pro
psandler
User
Posts: 540
Joined: 22-Feb-2005
# Posted on: 21-Apr-2005 18:57:06   

Thanks for the reply. Very interesting, and, as I said before, much to think about.

Otis wrote:

No, I wouldn't take that approach. My reasoning is that there is an X amount of work to be done. You use a given tool, in this case LLBLGen Pro to decrease that amount of work with, say, 30%. And then you increase the work again with an unknown factor without adding any (IMHO) real value . IMHO that's not the best way you can do things.

Now, with a bit of code generation, you can get very far in this though, so I'd suggest that IF you want to do this, look into code generation FIRST. See how you can create your own collection templates which generate generic classes and work with the generated llblgen pro classes, but I can assure you, you'll do a lot of the work again that's already be done for you . Life's complicated enough wink

I think the code generation option is interesting. Since I haven't played around with this aspect of the product (more because of time constraints than lack of interest), it's hard for me to envision what you mean. I would set up a mapping layer template set based on my BL model?

I understand what you mean when you say "life's complicated enough". Unfortunately, my hands are tied in this case.

Thanks again,

Phil

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39933
Joined: 17-Aug-2003
# Posted on: 22-Apr-2005 09:51:58   

psandler wrote:

Thanks for the reply. Very interesting, and, as I said before, much to think about.

Otis wrote:

No, I wouldn't take that approach. My reasoning is that there is an X amount of work to be done. You use a given tool, in this case LLBLGen Pro to decrease that amount of work with, say, 30%. And then you increase the work again with an unknown factor without adding any (IMHO) real value . IMHO that's not the best way you can do things.

Now, with a bit of code generation, you can get very far in this though, so I'd suggest that IF you want to do this, look into code generation FIRST. See how you can create your own collection templates which generate generic classes and work with the generated llblgen pro classes, but I can assure you, you'll do a lot of the work again that's already be done for you . Life's complicated enough wink

I think the code generation option is interesting. Since I haven't played around with this aspect of the product (more because of time constraints than lack of interest), it's hard for me to envision what you mean. I would set up a mapping layer template set based on my BL model?

With .lpt templates (templates written in C# or VB.NET) you can access the complete project object graph, and generate whatever code you want from that. This for example means that if you want own classes based on entity definitions and own collections for these, you can with 2 simple templates and also generate the code which sets/gets the data from generated entities.

I'd suggest you download template studio from the extra's section, get the SDK, and check out the manager templates available in the subversion repository at:

svn://www.sd.nl/LLBLGenPro

This will give you a good idea of what's possible simple_smile . The Template studio documentation comes with a few tutorials to get you started with template editing. Start simple, and you'll soon understand how to use the meta-data in the project object graph to generate code simple_smile

Frans Bouma | Lead developer LLBLGen Pro