What are we missing?

Posts   
 
    
jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 14-Jun-2005 22:44:15   

Hey, Frans. I'm wondering whether there are any features in the framework that you think are being underutilized. Or maybe there are some features you put a lot of sweat into and you're wondering how much they're being used?

I know in the software I develop I wonder if everyone's using the cool stuff I put in there, and I'm sure my clients would love to have a list of "must use" features they can review to make sure they're using them.

Just curious... simple_smile

Jeff...

Marcus avatar
Marcus
User
Posts: 747
Joined: 23-Apr-2004
# Posted on: 15-Jun-2005 09:51:49   

Great question!! I bet there's a ton of neat features that I don't use because I simply don't know about them... simple_smile

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39898
Joined: 17-Aug-2003
# Posted on: 15-Jun-2005 11:48:46   

jeffreygg wrote:

Hey, Frans. I'm wondering whether there are any features in the framework that you think are being underutilized. Or maybe there are some features you put a lot of sweat into and you're wondering how much they're being used?

Heh simple_smile well, one feature is of course more used than others. Selfservicing has more code of which I wonder 'will anyone every use it?' than adapter has, as adapter is more written based on user feedback than selfservicing is.

In selfservicing you for example have in the collection classes methods like: public bool GetMultiManyToOne(CustomerEntityBase,EmployeeEntityBase); This is entity specific, the above example is from an OrderCollection class. This then fetches the collection based on a passed in Customer entity OR employeeentity OR both, i.e. creates filters for you based on an existing entity.

Also the entity.SetCollectionParameters<field>() methods to set sorting/limitations for lazy loading, are these really used? I'm not sure simple_smile .

There are various ways to fetch a collection or entity, which way is more used than others, I'm not sure, but every way has its purpose, so I think it's good they're there, so in particular situations users can fall back to a different way to accomplish the same thing.

What I do want to know is how many people actually add code to the generated validator classes. The main issue is: I really want to update that interface, but I can't as it will break existing code bases because those classes will not be overwritten! simple_smile

In adapter you can already define multiple-entity-single table inheritance through factories, I'm sure not a lot are doing that at the moment simple_smile

There are always things you develop in a huge framework like LLBLGen Pro, of which you think later on... why on earth did I add it? I've long thought of myself "I never should have added custom properties", as they're a real pain sometimes, but a lot of people seem to be very happy with them, so I won't remove them simple_smile

Though I think one of the most unused features is in the code generator framework: I'm not sure if there are a lot who wrote their own task performer assembly (which is then used to run a task). LLBLGen Pro's generator framework is not a one-trick pony but a full hierarchical framework you can utilize to do whatever tasks you want, from checking out code, to compile your stuff and build an installer and mail it to you, just write the small task performer class that takes care of a single task simple_smile

One thing I will consider removing from the generated code is the excessive comments now used in the generated code, especially in classes not directly at the surface of the developer, as the comments increase the filesizes a lot while this is unnecessary.

A list of must-use features... hmm simple_smile Well, utilize the code generator more! that's the first advice I can give users: write own include templates and use the code generator to for example inject entity validator and concurrencypredicate factories at runtime for you without maintenance nightmares. The code generator framework is often overlooked, as it might seem 'complex' or 'a black box', while it's just an open framework you can extend in directions you want. I'm not sure a lot of people realize that, if I see how many people are so thrilled about codesmith while I can't see one single feature in codesmith our engine doesn't have, and then we're talking about a single task performer CLASS smile .

Frans Bouma | Lead developer LLBLGen Pro
wvnoort
User
Posts: 96
Joined: 06-Jan-2005
# Posted on: 15-Jun-2005 12:26:48   

Otis wrote:

In adapter you can already define multiple-entity-single table inheritance through factories, I'm sure not a lot are doing that at the moment

Now, you mention it. It was in the help files already. I think i am going to use it soon.

Otis wrote:

There are always things you develop in a huge framework like LLBLGen Pro, of which you think later on... why on earth did I add it? I've long thought of myself "I never should have added custom properties", as they're a real pain sometimes, but a lot of people seem to be very happy with them, so I won't remove them

Why on earth are people using it? For me there is an important thing missing: I cannot find a way to do a test in the template code whether a certain property is set. I would like to be able to add code to the initClassMember depending on whether or not a custom property is set.

I wrote some performer classes to keep custom user code after regeneration, but it isn't neccessary anymore with the current version. simple_smile

Marcus avatar
Marcus
User
Posts: 747
Joined: 23-Apr-2004
# Posted on: 15-Jun-2005 14:49:21   

Otis wrote:

There are always things you develop in a huge framework like LLBLGen Pro, of which you think later on... why on earth did I add it? I've long thought of myself "I never should have added custom properties", as they're a real pain sometimes, but a lot of people seem to be very happy with them, so I won't remove them

Never used these either... simple_smile

wvnoort wrote:

For me there is an important thing missing...

For me there are two things that I would love to see in the framework simple_smile

a) Fast client side collection searching. I wouldn't want this on by default because of the overhead of filling Hashtables etc, but being able to get directly to a given Entity within the collection is something that would be very usefull.

b) A caching layer... I think with the new database cache invalidation features of SQL Server 2005, LLBLGen will be perfectly positioned to incorprate sophisticated and configurable data caching into the framework. This has enormous potential to improve application performance across the board and is something I really hope you will consider including for v2.0 smile

Marcus

jeffreygg
User
Posts: 805
Joined: 26-Oct-2003
# Posted on: 15-Jun-2005 21:09:34   

Otis wrote:

jeffreygg wrote:

Hey, Frans. I'm wondering whether there are any features in the framework that you think are being underutilized. Or maybe there are some features you put a lot of sweat into and you're wondering how much they're being used?

Heh simple_smile well, one feature is of course more used than others. Selfservicing has more code of which I wonder 'will anyone every use it?' than adapter has, as adapter is more written based on user feedback than selfservicing is.

In selfservicing you for example have in the collection classes methods like: public bool GetMultiManyToOne(CustomerEntityBase,EmployeeEntityBase); This is entity specific, the above example is from an OrderCollection class. This then fetches the collection based on a passed in Customer entity OR employeeentity OR both, i.e. creates filters for you based on an existing entity.

Also the entity.SetCollectionParameters<field>() methods to set sorting/limitations for lazy loading, are these really used? I'm not sure simple_smile .

Man, I haven't used Self Servicing in ages. I do miss it sometimes, but I'll never go back (at least for the type of work I'm doing now). The thing I (of course) really miss is lazy loading. I wonder if there is any way to get the power of Adapter with the ease of use of lazy loading? Conceptually, I'm thinking of some sort of data context that the entities have that holds a reference to an Adapter...I don't know. It would just be nice to have in places where the system isn't distributed. simple_smile

There are various ways to fetch a collection or entity, which way is more used than others, I'm not sure, but every way has its purpose, so I think it's good they're there, so in particular situations users can fall back to a different way to accomplish the same thing.

What I do want to know is how many people actually add code to the generated validator classes. The main issue is: I really want to update that interface, but I can't as it will break existing code bases because those classes will not be overwritten! simple_smile

For my current project I don't use these at all as my client feels that data validation is an unnecessary luxury. rage (!!)

In adapter you can already define multiple-entity-single table inheritance through factories, I'm sure not a lot are doing that at the moment simple_smile

Yea, I'm not using that. simple_smile

There are always things you develop in a huge framework like LLBLGen Pro, of which you think later on... why on earth did I add it? I've long thought of myself "I never should have added custom properties", as they're a real pain sometimes, but a lot of people seem to be very happy with them, so I won't remove them simple_smile

I do use them. Or, more accurately, I have use for them soon. simple_smile My use is to give entities a friendly name. I use this when creating the title for detail forms, for example. It's nice. simple_smile

Though I think one of the most unused features is in the code generator framework: I'm not sure if there are a lot who wrote their own task performer assembly (which is then used to run a task). LLBLGen Pro's generator framework is not a one-trick pony but a full hierarchical framework you can utilize to do whatever tasks you want, from checking out code, to compile your stuff and build an installer and mail it to you, just write the small task performer class that takes care of a single task simple_smile

While it probably wouldn't result in a significant increase in task performer writing, what about writing a couple of fun ones that you know people would use as a demonstration of their power? I hadn't really understood myself all the things one could do with them. I like the "compile your stuff" idea. I wonder if there should be some sort of Template and Task Performer management UI...something that allows one to catalog, organize and update the list of templates and task performers available for use in the framework...

One thing I will consider removing from the generated code is the excessive comments now used in the generated code, especially in classes not directly at the surface of the developer, as the comments increase the filesizes a lot while this is unnecessary.

A list of must-use features... hmm simple_smile Well, utilize the code generator more! that's the first advice I can give users: write own include templates and use the code generator to for example inject entity validator and concurrencypredicate factories at runtime for you without maintenance nightmares. The code generator framework is often overlooked, as it might seem 'complex' or 'a black box', while it's just an open framework you can extend in directions you want.

I don't know why I have an aversion to writing templates. I think you're right about it seeming complex or black-boxish. I have messed with them a little bit. I think deep down I'm worried about the templates breaking when new releases come out, even though for self-contained templates I'm sure that's not a problem.

I'm not sure a lot of people realize that, if I see how many people are so thrilled about codesmith while I can't see one single feature in codesmith our engine doesn't have, and then we're talking about a single task performer CLASS smile .

Have you considered decoupling the generator functionality from the Designer? I personally might be more apt to use it for generic code generation if it was more or less available outside of the Designer. You also might have a viable competitor to CodeSmith if you did something like that. Lord knows your Template Studio r0x0rs. simple_smile

Marcus wrote:

a) Fast client side collection searching. I wouldn't want this on by default because of the overhead of filling Hashtables etc, but being able to get directly to a given Entity within the collection is something that would be very usefull.

Yea, that would be nice. Although this might come with the object query language coming in V2? Or is that only for persisted data?

b) A caching layer... I think with the new database cache invalidation features of SQL Server 2005, LLBLGen will be perfectly positioned to incorprate sophisticated and configurable data caching into the framework. This has enormous potential to improve application performance across the board and is something I really hope you will consider including for v2.0 smile

I wholeheartedly agree. I've mentioned this before as the new SQL caching functionality opens up quite a bit of possibilities.


I think what I really want to see is an "Upper Layer" (UL) framework add-on to LLBLGen Pro that sits on top of the existing LLBL entities and collections and services the Presentation, Facade, Process, and/or Upper Layer Business Layers. I've mentioned this before also. I really need to write up a more formal proposal...Some possible features:

-Client-side caching framework -A more robust, PL-oriented, validation framework (not exception-based) -Easier, perhaps more directed construction of presentation/display objects with databinding -Perhaps complete in-memory objects graphs (client-side, of course) -Complete object graph tracking and versioning

Jeff...

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39898
Joined: 17-Aug-2003
# Posted on: 16-Jun-2005 11:16:53   

wvnoort wrote:

Otis wrote:

There are always things you develop in a huge framework like LLBLGen Pro, of which you think later on... why on earth did I add it? I've long thought of myself "I never should have added custom properties", as they're a real pain sometimes, but a lot of people seem to be very happy with them, so I won't remove them

Why on earth are people using it? For me there is an important thing missing: I cannot find a way to do a test in the template code whether a certain property is set. I would like to be able to add code to the initClassMember depending on whether or not a custom property is set. I wrote some performer classes to keep custom user code after regeneration, but it isn't neccessary anymore with the current version. simple_smile

I've added the compare to custom property statement to the 1.0.2005.1 upgrade features, it's a very powerful addition I think. The custom properties are often used for defining hints for runtime code, like gui code.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39898
Joined: 17-Aug-2003
# Posted on: 16-Jun-2005 11:21:12   

Marcus wrote:

For me there are two things that I would love to see in the framework simple_smile

a) Fast client side collection searching. I wouldn't want this on by default because of the overhead of filling Hashtables etc, but being able to get directly to a given Entity within the collection is something that would be very usefull.

They're already on the todo simple_smile

b) A caching layer... I think with the new database cache invalidation features of SQL Server 2005, LLBLGen will be perfectly positioned to incorprate sophisticated and configurable data caching into the framework. This has enormous potential to improve application performance across the board and is something I really hope you will consider including for v2.0 smile Marcus

Caching with 2005/oracle invalidation services can be a plus, though without these it's pretty meaningless I think (as in: it's only overhead, no real gain).

Don't have the illusion a cache is faster, it's slower. It's only faster if you pull single objects, (can be faster). For multi-entity selects, it's slower, as the query always has to go to the db, fetch all data, and update the cached objects. Something which is already been taken care of by the context.

The only way a cache can be faster is when you cache query results. Though I'd not recommend these, as caching query results for re-use is IMHO not that wise, unless you KNOW it's data which hardly changes.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39898
Joined: 17-Aug-2003
# Posted on: 16-Jun-2005 11:28:12   

jeffreygg wrote:

Though I think one of the most unused features is in the code generator framework: I'm not sure if there are a lot who wrote their own task performer assembly (which is then used to run a task). LLBLGen Pro's generator framework is not a one-trick pony but a full hierarchical framework you can utilize to do whatever tasks you want, from checking out code, to compile your stuff and build an installer and mail it to you, just write the small task performer class that takes care of a single task simple_smile

While it probably wouldn't result in a significant increase in task performer writing, what about writing a couple of fun ones that you know people would use as a demonstration of their power? I hadn't really understood myself all the things one could do with them. I like the "compile your stuff" idea. I wonder if there should be some sort of Template and Task Performer management UI...something that allows one to catalog, organize and update the list of templates and task performers available for use in the framework...

yes, I know what you mean. Now the generator configs aren't updatable in a gui, just in xml.

There is a small task performer which creates folders, which is available in sourcecode (like the others). Which could be seen as a smallish example. Though perhaps users need more appealing ones.

One thing I will consider removing from the generated code is the excessive comments now used in the generated code, especially in classes not directly at the surface of the developer, as the comments increase the filesizes a lot while this is unnecessary.

A list of must-use features... hmm simple_smile Well, utilize the code generator more! that's the first advice I can give users: write own include templates and use the code generator to for example inject entity validator and concurrencypredicate factories at runtime for you without maintenance nightmares. The code generator framework is often overlooked, as it might seem 'complex' or 'a black box', while it's just an open framework you can extend in directions you want.

I don't know why I have an aversion to writing templates. I think you're right about it seeming complex or black-boxish. I have messed with them a little bit. I think deep down I'm worried about the templates breaking when new releases come out, even though for self-contained templates I'm sure that's not a problem.

It's also the necessity to learn something new, you can't just jump in, write some code and get things going. THough it's often very rewarding simple_smile

I'm not sure a lot of people realize that, if I see how many people are so thrilled about codesmith while I can't see one single feature in codesmith our engine doesn't have, and then we're talking about a single task performer CLASS smile .

Have you considered decoupling the generator functionality from the Designer? I personally might be more apt to use it for generic code generation if it was more or less available outside of the Designer. You also might have a viable competitor to CodeSmith if you did something like that. Lord knows your Template Studio r0x0rs. simple_smile

Code generation requires meta-data. So to get a code generator to work, you have to supply meta-data. The meta-data in the code generator engines here, is a .lgp project. You can also use your own meta-data of course, but you then have to read it in yourself, and use an .lpt template to read/utilize it.

Marcus wrote:

a) Fast client side collection searching. I wouldn't want this on by default because of the overhead of filling Hashtables etc, but being able to get directly to a given Entity within the collection is something that would be very usefull.

Yea, that would be nice. Although this might come with the object query language coming in V2? Or is that only for persisted data?

Only for persisted data.

Frans Bouma | Lead developer LLBLGen Pro
Marcus avatar
Marcus
User
Posts: 747
Joined: 23-Apr-2004
# Posted on: 16-Jun-2005 12:45:20   

Otis wrote:

b) A caching layer... I think with the new database cache invalidation features of SQL Server 2005, LLBLGen will be perfectly positioned to incorprate sophisticated and configurable data caching into the framework. This has enormous potential to improve application performance across the board and is something I really hope you will consider including for v2.0 smile Marcus

Caching with 2005/oracle invalidation services can be a plus, though without these it's pretty meaningless I think (as in: it's only overhead, no real gain).

Don't have the illusion a cache is faster, it's slower. It's only faster if you pull single objects, (can be faster). For multi-entity selects, it's slower, as the query always has to go to the db, fetch all data, and update the cached objects. Something which is already been taken care of by the context.

Slower.... Doesn't that all depend on the cache implementation and operating envrironment?

Without the new auto cache invalidation, invalidating stale data in the middle tiers (where there is more than 1 server caching the data) becomes very hard. But with the new invalidation mechanism, this becomes much simpler.

I always consider caching IS faster, but then I'm also asumming that the cache is not being misused. If a valid copy of some data is available in memory, then this will ALWAYS be faster than crossing a network boundary to ask the database for it.

Otis wrote:

The only way a cache can be faster is when you cache query results.

I understand that for fetching sets of data, trying to avail of partial data in the cache and partial data from the DB is going to be slower... granted... but then you should only be looking in the cache to see if the entire resultset is available as you say. The invalidation policy would invalidate then entire resultset if any of its contents changed. I also see that the cache could store individual Entities which were previously fetched as a collection. Even if the resultset (collection) is invalidated, the majority of the remaining entities would survive.

Otis wrote:

Though I'd not recommend these, as caching query results for re-use is IMHO not that wise, unless you KNOW it's data which hardly changes.

But that's exactly what the 2005's cache invalidation gives you... wink

It all boils down to cache policy and being able to specify how (and if) data should be cached on a per fetch basis...

It sounds like your not a fan of caching and is probably the reason why its not already a feature of the framework. simple_smile ... But hopefully you'll change your mind! stuck_out_tongue_winking_eye

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39898
Joined: 17-Aug-2003
# Posted on: 17-Jun-2005 11:06:20   

Marcus wrote:

Otis wrote:

b) A caching layer... I think with the new database cache invalidation features of SQL Server 2005, LLBLGen will be perfectly positioned to incorprate sophisticated and configurable data caching into the framework. This has enormous potential to improve application performance across the board and is something I really hope you will consider including for v2.0 smile Marcus

Caching with 2005/oracle invalidation services can be a plus, though without these it's pretty meaningless I think (as in: it's only overhead, no real gain).

Don't have the illusion a cache is faster, it's slower. It's only faster if you pull single objects, (can be faster). For multi-entity selects, it's slower, as the query always has to go to the db, fetch all data, and update the cached objects. Something which is already been taken care of by the context.

Slower.... Doesn't that all depend on the cache implementation and operating envrironment?

No simple_smile

Without the new auto cache invalidation, invalidating stale data in the middle tiers (where there is more than 1 server caching the data) becomes very hard. But with the new invalidation mechanism, this becomes much simpler.

I always consider caching IS faster, but then I'm also asumming that the cache is not being misused. If a valid copy of some data is available in memory, then this will ALWAYS be faster than crossing a network boundary to ask the database for it.

In theory, you're right. In practise, you don't know if all data available in the database is available in your cache. Say I want all customers who placed an order yesterday. Say that there are 10 customers in that set in the database, 5 of them are in my cache. If I start on the client, I have 2 options: ask the cache, and I'll get 5 or ask the db and I'll get 10.

So, to be sure my client uses the correct data, I have to consult the database. I then make the roundtrip, execute the query and get data returned. Some clever people might now say: "what if you query for just the PK's? then you match them with the cache, and only fetch the ones not in the cache!", but that's not correct either, as a cached object might be out of sync with its data in the db because another user updated the entity in the db.

(only if you store versioning info in the db as well, i.e. require it. Though requireing that is too much of a burden for relational model designers: I don't want to force anything on a relational model designer).

So you've to fetch the complete set of 10 customers, and then update the cached objects, and return these 5 instances with the updated data and the 5 new ones.

I.o.w.: pretty silly construct if you ask me, only useful for uniquing (i.e. unique instances) wink .

Otis wrote:

The only way a cache can be faster is when you cache query results.

I understand that for fetching sets of data, trying to avail of partial data in the cache and partial data from the DB is going to be slower... granted... but then you should only be looking in the cache to see if the entire resultset is available as you say. The invalidation policy would invalidate then entire resultset if any of its contents changed. I also see that the cache could store individual Entities which were previously fetched as a collection. Even if the resultset (collection) is invalidated, the majority of the remaining entities would survive.

Though a collection can also be expanded by a different thread adding a new entity: you've a set of 9 customers in your cache, another user adds a new user, which would meet your query requirements, how would you get that 10th customer in your cache? Only by requerying the DB.

The problem is that the BL tier isn't aware of object instances in other appdomains on other systems. On Java, where you can have a cross-server system cache like JBoss offers, you can KNOW when another user adds a new customer, so you can tell that a new customer is available so when you query the cache for the customers, you're automatically told there is a 10th one and it's added to your cache (or better: every appdomain reads from the same cache)

So to solve this, every db activity has to flow through the same cache, which can be a server with the same security stuff as sqlserver has. I then think: but sqlserver already caches everything and I do need to make a network roundtrip anyway... so re-querying the db isn't that bad.

Otis wrote:

Though I'd not recommend these, as caching query results for re-use is IMHO not that wise, unless you KNOW it's data which hardly changes.

But that's exactly what the 2005's cache invalidation gives you... wink

Only for changes in existing rows. It's not strange they implemented this on the ASP.NET level. It makes sure that processing results which are cached, should be invalidated because the data used for the processing is changed. Though when a new row is added to a table, it too should invalidate the cache, though I'm pretty sure (haven't checked) that's almost impossible to achieve for a database server.

It all boils down to cache policy and being able to specify how (and if) data should be cached on a per fetch basis...

Though it's too low level and you miss new data. IMHO people should focus on caching processed results. Take this forum for example. When you click 'Post' the parser parses the text to XML and via an XSL it's converted to HTML. The HTML for a posting is then stored in the DB together with the original text. The viewer for a thread pulls only the HTML snippets in the right order. The HTML is 'cached' in the DB until the user changes his / her posting. I didn't implement it, but I could cache the thread HTML as well using ASP.NET caching, and invalidate it when a user changed the posting, as I know when that happens. (I do that with the RSS feeds btw: these are cached till a posting in the list of 50 postings is changed)

It boils down to: cache as high up in the app-stack as possible and invalidate from top to bottom, as you know when things change at the top and not at the bottom.

For websites it's even easier: the content is by definition stale. So a very good performance gain for very frequently visited websites is to pre-render the vast majority of the site, every X seconds, where X is a time interval which is easily met by the hardware. If visits increase, X increases as well, causing a website which is always available.

It sounds like your not a fan of caching and is probably the reason why its not already a feature of the framework. simple_smile ... But hopefully you'll change your mind! stuck_out_tongue_winking_eye

Caching is nice, but I dont want to add a cache to the lower levels of an app just because others do so, while its not correct and will cause problems for users. With the context I've tried to address the single point caches do have: uniquing, for the rest I think data-caches are there for marketing reasons and not for performance reasons, as they don't make sense for performance tuning, as I tried to describe above (in fact, it's slower, you have to invalidate objects in your cache based on data read from the db).

Frans Bouma | Lead developer LLBLGen Pro
Marcus avatar
Marcus
User
Posts: 747
Joined: 23-Apr-2004
# Posted on: 17-Jun-2005 19:59:20   

Frans, as usual you make some excellent points there simple_smile especially regarding INSERT invalidation. I get the impression that this will only work if the entire table is invalidated as a result of a single insert, which of course would in practice render any cache useless other than for very stable data.

I agree that caching should be as high as possible up the stack in order to increase its efficiency and maybe the only real benefit of a cache in LLBLGen is for single Entity fecthes...

Have a good weekend!

eugene
User
Posts: 85
Joined: 05-Oct-2004
# Posted on: 20-Jun-2005 12:33:25   

Hi there,

a short note to the generated validator classes. I make extensive use of validator classes, yet I don't use the generated ones. Here is how I use the Validator classes

  • Actual tests are seperated from the validator class, and can be called from the validator
  • Validators have their own base class which accepts an adapter in the constructor
  • Validations are divided into three types (using an enum): save validations delete validation mere validations that don't accompany a DB-operation
  • A validator determines (through a switch instruction) upon having the validate member called, which of the defined tests needs to be run.
  • I use an extended Validationexception class that holds the name of the entity field that caused the error
  • The gui can extract this information and shows the error information right at the control associated with the entity field

I only write a validator once I have an explicit need for it. A Function SetValidator(Entity) determines the right validator for the entity.

This is one (of the many wink ) really fine ideas in LLBLGen and it's proving to be very helpful reacting to changing user needs and wishes! What kind of changes did you have in mind, Otis?

Best regards

Rogelio
User
Posts: 221
Joined: 29-Mar-2005
# Posted on: 20-Jun-2005 15:30:23   

Frans,

I agree with you, I think caching could become a big problem is you implement it. I have seem other product that after implementing caching, become a big unstable product. If by any way you are going to implement caching, then please leave it as an option that could be enable or disable.

Answer
User
Posts: 363
Joined: 28-Jun-2004
# Posted on: 20-Jun-2005 18:17:33   

A list of must-use features... hmm Well, utilize the code generator more! that's the first advice I can give users: write own include templates and use the code generator to for example inject entity validator and concurrencypredicate factories at runtime for you without maintenance nightmares. The code generator framework is often overlooked, as it might seem 'complex' or 'a black box', while it's just an open framework you can extend in directions you want. I'm not sure a lot of people realize that, if I see how many people are so thrilled about codesmith while I can't see one single feature in codesmith our engine doesn't have, and then we're talking about a single task performer CLASS .

I think the reason more people don't use it, or at least for me is that when i looked into it, i found it kinda confusing and difficult to learn. With codesmith, i almost could just jump in, i read about 10-15 minutes worth of material and i understood most stuff. I could jump in writing templates very very quickly. The other advantage codesmith HAD was a template studio, which i requested from you and u now have wink So there is no real advantage to codesmith in that area now. To be honest i havent looked into your code gen since my initial look a while back (prior to having the template studio). I think some easy to understand tutorials that display the raw power and simplicity of your codegen engine would help a lot as to me it was confusing and difficult to understand. Most of my development stuff i do for fun, if i cant figure something out quickly i get annoyed and move on stuck_out_tongue_winking_eye

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39898
Joined: 17-Aug-2003
# Posted on: 20-Jun-2005 21:44:17   

eugene wrote:

Hi there,

a short note to the generated validator classes. I make extensive use of validator classes, yet I don't use the generated ones. Here is how I use the Validator classes

  • Actual tests are seperated from the validator class, and can be called from the validator
  • Validators have their own base class which accepts an adapter in the constructor
  • Validations are divided into three types (using an enum): save validations delete validation mere validations that don't accompany a DB-operation
  • A validator determines (through a switch instruction) upon having the validate member called, which of the defined tests needs to be run.
  • I use an extended Validationexception class that holds the name of the entity field that caused the error
  • The gui can extract this information and shows the error information right at the control associated with the entity field

I only write a validator once I have an explicit need for it. A Function SetValidator(Entity) determines the right validator for the entity.

This is one (of the many wink ) really fine ideas in LLBLGen and it's proving to be very helpful reacting to changing user needs and wishes! What kind of changes did you have in mind, Otis?

Great feedback! simple_smile Changes which are around the corner are inheritance, multiple entities on the same table, optional fields etc., really flexibility options to make working with the entities much easier. The one thing which I can't get into this upgrade but which will be a cornerstone of v2.0 is validation based on designed rules (i.e. defined in the designer). I do have planned more validation options in 1.0.2005.1's generated code, so it should be easier to write validation code and get validation in place.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39898
Joined: 17-Aug-2003
# Posted on: 20-Jun-2005 21:46:20   

Rogelio wrote:

Frans, I agree with you, I think caching could become a big problem is you implement it. I have seem other product that after implementing caching, become a big unstable product. If by any way you are going to implement caching, then please leave it as an option that could be enable or disable.

I think the context object as it is now is as far as I want to go. Even if I wanted to, I think adding a reliable cache is undoable. At least without cross-appdomain object awareness, something which isn't available in .NET at the moment. (without com+)

Frans Bouma | Lead developer LLBLGen Pro
jtgooding
User
Posts: 126
Joined: 26-Apr-2004
# Posted on: 20-Jun-2005 22:25:10   

I tried to use the Validators of LLBLGen early on, but quickly found them too limiting, the base validator does not pass in a reference to the entity, so there is no way of doing if field A is true then field B can only be these values etc.

Then there is the EntityValidator which must be manually called when you use the Field Validator mentioned above, I ended up using a model almost identical to your IValidator interface, I just modifed it to work in our business layer instead of the entity layer, and it takes a different set of parameters to overcome what we saw were limitations.

The feature that I am hoping is still coming in the next version is to enable system functions as predicates, SubString, Left, trim, isnull, etc. etc. This is quickly becoming the only reason I have to write procs anymore, especially when used as a join condition.

John

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39898
Joined: 17-Aug-2003
# Posted on: 21-Jun-2005 11:32:33   

jtgooding wrote:

I tried to use the Validators of LLBLGen early on, but quickly found them too limiting, the base validator does not pass in a reference to the entity, so there is no way of doing if field A is true then field B can only be these values etc.

That's where the IEntityValidator objects are for simple_smile . The IValidator objects are for field value validation, i.e. CustomerID > 0, they're called when a field gets a value. Because the order in which fields are set is undetermined, doing checks across fields in there is not what you want as it might determine an error while a field hasn't been set yet.

Then there is the EntityValidator which must be manually called when you use the Field Validator mentioned above, I ended up using a model almost identical to your IValidator interface, I just modifed it to work in our business layer instead of the entity layer, and it takes a different set of parameters to overcome what we saw were limitations.

IEntityValidator objects are called when an entity is saved as well. Which makes sure only validated objects are saved to the db.

The feature that I am hoping is still coming in the next version is to enable system functions as predicates, SubString, Left, trim, isnull, etc. etc. This is quickly becoming the only reason I have to write procs anymore, especially when used as a join condition. John

I've it on my plate indeed, the main issue is to come up with an easy way to embed them, as they're very db specific.

Frans Bouma | Lead developer LLBLGen Pro
Otis avatar
Otis
LLBLGen Pro Team
Posts: 39898
Joined: 17-Aug-2003
# Posted on: 22-Jun-2005 10:43:54   

Answer wrote:

A list of must-use features... hmm Well, utilize the code generator more! that's the first advice I can give users: write own include templates and use the code generator to for example inject entity validator and concurrencypredicate factories at runtime for you without maintenance nightmares. The code generator framework is often overlooked, as it might seem 'complex' or 'a black box', while it's just an open framework you can extend in directions you want. I'm not sure a lot of people realize that, if I see how many people are so thrilled about codesmith while I can't see one single feature in codesmith our engine doesn't have, and then we're talking about a single task performer CLASS .

I think the reason more people don't use it, or at least for me is that when i looked into it, i found it kinda confusing and difficult to learn. With codesmith, i almost could just jump in, i read about 10-15 minutes worth of material and i understood most stuff. I could jump in writing templates very very quickly.

Though that's not true anymore, as you can write a C# template with the new template engines as well for LLBLGen Pro, plus you had to figure out the meta-data structure for codesmith anyway. With TDL statements it's not that obvious indeed, and you had to learn a complete new language, which is not able to do everything.

Frans Bouma | Lead developer LLBLGen Pro
Answer
User
Posts: 363
Joined: 28-Jun-2004
# Posted on: 22-Jun-2005 16:39:24   

Though that's not true anymore, as you can write a C# template with the new template engines as well for LLBLGen Pro, plus you had to figure out the meta-data structure for codesmith anyway. With TDL statements it's not that obvious indeed, and you had to learn a complete new language, which is not able to do everything.

Yeah, its been a bit since i looked into it. That was just my experience when i did try to do some code gen back in the day smile c# templates werent available then. I'll have some stuff i can generate on my next project so i will look into it again.