common interface for >1 generated entity objects

Posts   
 
    
mkamoski avatar
mkamoski
User
Posts: 116
Joined: 06-Dec-2005
# Posted on: 07-Apr-2006 17:00:05   

All--

Please help.

I want to have an interface that covers several generated entity objects.

My first guess is that I would want my generated objects to have "Implements ISpecialObject" in them. That's how I have done this before, with code-generation, with OR-mapping, and with hand-coded classes.

However, I would rather not have to use code-preservation with LLBLGen.

Therefore, I am not sure what to do.

Maybe somekind of inheritace scheme?

What are others doing?

What is recommended?

Please advise.

--Mark Kamoski

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39749
Joined: 17-Aug-2003
# Posted on: 07-Apr-2006 18:10:51   

If you're on .NET 2.0, you can use partial classes.

In v2, we'll add a way to specify additional interfaces for one or more entities to implement which is then generated into the code. (you then still have to implement the interfaces but you get the interface added to the class def.)

Frans Bouma | Lead developer LLBLGen Pro
mkamoski avatar
mkamoski
User
Posts: 116
Joined: 06-Dec-2005
# Posted on: 07-Apr-2006 19:08:58   

Otis--

Regarding this...

Otis wrote:

If you're on .NET 2.0, you can use partial classes...

...unfortunately, I have to report that I am stuck in .NET 1.1 for the time being.

I have had some success making generic object wrappers using composition; but, the Type management and casting is driving me bonkers; but, it does hide all the messy stuff in one place and it does work. Of course, it is a bit fragile, which is not so good but it is GEFN.

However, I would be interested to hear if you have any other ideas, other than a generic object wrapper using composition?

Please advise.

Thank you.

--Mark Kamoski

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39749
Joined: 17-Aug-2003
# Posted on: 08-Apr-2006 12:05:43   

Composition can work out fine, the problem starts with hierarchies. For example Customer contains Orders, Order contains OrderRows. If you want to encapsulate Customer in something, call it A, and A should contain Orders instead, you're out of luck.

Frans Bouma | Lead developer LLBLGen Pro
mkamoski avatar
mkamoski
User
Posts: 116
Joined: 06-Dec-2005
# Posted on: 10-Apr-2006 15:05:46   

Otis wrote:

Composition can work out fine, the problem starts with hierarchies...

Yes, that's what I have found.

Luckily, in the current case, I am dealing with leaf or "near-leaf" tables and objects.

Thank you.

--Mark Kamoski

mkamoski avatar
mkamoski
User
Posts: 116
Joined: 06-Dec-2005
# Posted on: 18-Apr-2006 18:13:06   

Otis wrote:

Composition can work out fine...

Otis, if possible, please do comment on my message below to Steve, our project's Tech Manager, regarding implementing an interface for LLBLGen classes.

Note-- I know that there exists some kind of "code table implementation framework for LLBLGen, or something like that, but I do not want to use that for various reason. So, let's set that aside for the sake of this discussion right now.

Note-- We are working in .NET 1.1.

So, Otis, what do you think?

Please advise.

Thank you.

--Mark Kamoski

-----Original Message----- From: Kamoski, Mark Sent: Tuesday, April 18, 2006 11:57 To: Steve Subject: implementing an interface for LLBLGen classes

Steve--

I have some questions about how our team should be implementing an interface (or some other generic object referencing schema) for LLBLGen classes.

Basically, this is the case where one wants to handle a set of objects (such as code table objects) generically.

Since LLBLGen does not support the use of Interfaces directly, then one has to do something else.

As far as I tell, there are at least 3 options.

(1). Use code preservation tags. Put them in the generated classes as-needed. The code will not get overwritten.

Pros-- Solves the problem.

Cons-- Nasty code to write. Not very clean. Complicates the build process given that generated classes are not kept in SourceSafe. Makes it such that one should not "just delete all the generated code from your local machine before regenerating to avoid file locking issues" during the LLBLGen regeneration from the LLBLGen project file. May not support the complete variety of code that one wants to add and whether or not it does support what one wants to do probably requires some test implementation.

(2). Create a composite object that can hold any object in a given list of compatible objects. The composite holds a reference to the specific type but exposes common properties and methods via a generic interface.

Pros-- Solves the problem. Does not use code preservation tags, so it avoids the cons to code-preservation.

Cons-- There is a lot of casting that needs a lot of manual maintenance if new implementing objects are added. The collection object for such a class is non-trivial.

(3). Use a combination of inheritance and an interface. Create a simple helper class for each entity that needs to be generic. Have this helper class inherit from the actual specific entity class and, at the same time, implement a generic interface.

Pros-- Solves the problem. Has the minimal maintenance of these 3 options. Is simple. Is direct. Use OOP. Can then add additional implementation code if the implementing objects need to do special processing.

Cons-- Requires some maintenance to the interface and implementing classes. Require the addition of a class for each object that needs to be generic.

...or, maybe there is a better way?

I think that Option (3) is best?

What do you think?

Please advise.

Thank you.

--Mark

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39749
Joined: 17-Aug-2003
# Posted on: 19-Apr-2006 11:41:24   

Ok here it goes simple_smile

Be aware of the fact that in v2 you'll be able to specify which interfaces should be implemented by which entities and these are generated (not the methods, just the interface derive statements in the class definition header) into the code. You can then opt for example for an include template to generate the stubs of the interface into code IF you want to, though you can also opt for implementing it in a code region.

-----Original Message----- From: Kamoski, Mark Sent: Tuesday, April 18, 2006 11:57 To: Steve Subject: implementing an interface for LLBLGen classes

Steve--

I have some questions about how our team should be implementing an interface (or some other generic object referencing schema) for LLBLGen classes.

Basically, this is the case where one wants to handle a set of objects (such as code table objects) generically.

Since LLBLGen does not support the use of Interfaces directly, then one has to do something else.

As far as I tell, there are at least 3 options.

(1). Use code preservation tags. Put them in the generated classes as-needed. The code will not get overwritten.

Pros-- Solves the problem.

Cons-- Nasty code to write. Not very clean. Complicates the build process given that generated classes are not kept in SourceSafe. Makes it such that one should not "just delete all the generated code from your local machine before regenerating to avoid file locking issues" during the LLBLGen regeneration from the LLBLGen project file. May not support the complete variety of code that one wants to add and whether or not it does support what one wants to do probably requires some test implementation.

That's indeed a point, though it can be the best option you'll have for .NET 1.x.

(2). Create a composite object that can hold any object in a given list of compatible objects. The composite holds a reference to the specific type but exposes common properties and methods via a generic interface.

Pros-- Solves the problem. Does not use code preservation tags, so it avoids the cons to code-preservation.

Cons-- There is a lot of casting that needs a lot of manual maintenance if new implementing objects are added. The collection object for such a class is non-trivial.

composition is ok, but indeed can give problems with hierarchies.

(3). Use a combination of inheritance and an interface. Create a simple helper class for each entity that needs to be generic. Have this helper class inherit from the actual specific entity class and, at the same time, implement a generic interface.

Pros-- Solves the problem. Has the minimal maintenance of these 3 options. Is simple. Is direct. Use OOP. Can then add additional implementation code if the implementing objects need to do special processing.

Cons-- Requires some maintenance to the interface and implementing classes. Require the addition of a class for each object that needs to be generic.

This also has a problem with hierarchies. However you can use templates for this. If you're using adapter, you can use the derived entity templates for adapter and modify them a bit so they generate the interface into the class automatically. This then solves the hierarchy problem as these classes are already prepared for that simple_smile

Frans Bouma | Lead developer LLBLGen Pro
mkamoski avatar
mkamoski
User
Posts: 116
Joined: 06-Dec-2005
# Posted on: 21-Apr-2006 17:55:49   

All--

FWIW, as a follow-up to my posts above, I would like to report that I am having very good luck with Option (3)-- create a common API for a set of objects by "Using a combination of inheritance and an interface. Create a simple helper class for each entity that needs to be generic. Have this helper class inherit from the actual specific entity class and, at the same time, implement a generic interface".

Note, however, that this did necessitate some (ugly) factory-patterned method wrappers around the Adapter. I did this by making a simple helper for the set of generic objects and exposing a few Shared methods that take a Type (the underlying type) and sometimes the generic entity itself and provide a pass-through to the standard DataAccessAdapter's SaveEntity, FetchEntity, and some typed-helpers such as GetNewGenericEntity(type) and GetNewGenericEntityCollection(type).

Anyway, I am finding this to be quite workable, easy to build and maintain. Most everything is a pass-through to the underlying object, but there are few type-converter factories to maintain, which is less-than-ideal but that's usually the case with factory-style methods.

Note that these objects are leaf-object (not hierarchical). Yet. Therefore, I not see the issues that Otis warns about yet-- (but I have courage that I will be able to deal with that requirement if/when it arises).

I just thought I would "share".

:-)

HTH.

Thank you.

--Mark Kamoski