- Home
- General
- General Chat
Refactoring the ORM Support Classes?
Joined: 04-Feb-2004
I think that the majority of us would agree that LLBLGen rocks, and it is a huge time saver, and it's a must have for every developer's toolbox.
As the product moves foward, I was curious to know if you had given any though to refactoring the DataAccessAdapter or IDataAccessAdapter interface to make it more composite.
There are many overloads for doing things with entities, collections, typed views, typed lists, action procedures, and retreival procedures.
In many scenarios, I would like to wrap this functionality into my own classes, but in order to do so, I must either implement all of IDataAccessAdapter or inherit from DataAccessAdapter.
So, if you created an interface for each functional area of a data access adapter, I could simply implement the interface IFetchTypedView or IFetchCollection and all the overloads would be available for me to implement in my own classes without having to implement the entire IDataAccessAdapter interface or DataAccessAdapter base class.
Has this been considered for future versions of LLBLGen Pro?
Joined: 17-Aug-2003
Devildog74 wrote:
I think that the majority of us would agree that LLBLGen rocks, and it is a huge time saver, and it's a must have for every developer's toolbox.
As the product moves foward, I was curious to know if you had given any though to refactoring the DataAccessAdapter or IDataAccessAdapter interface to make it more composite.
Every revision some refactoring is done, but mostly building on top of existing code, as splitting up classes is not possible without having a lot of problems on teh migration front and that's unacceptable . But I do look at refactoring stuff behind the scenes, so it gets more streamlined and still has the same interfaces .
There are many overloads for doing things with entities, collections, typed views, typed lists, action procedures, and retreival procedures.
In many scenarios, I would like to wrap this functionality into my own classes, but in order to do so, I must either implement all of IDataAccessAdapter or inherit from DataAccessAdapter.
So, if you created an interface for each functional area of a data access adapter, I could simply implement the interface IFetchTypedView or IFetchCollection and all the overloads would be available for me to implement in my own classes without having to implement the entire IDataAccessAdapter interface or DataAccessAdapter base class. Has this been considered for future versions of LLBLGen Pro?
Keep in mind that the interface IDataAccessAdapter is there to make transparent usage of different DataAccessAdapter classes possible by the same code. Almost all code is in the DataAccessAdapterBase class.
So the times you have to implement such an interface are not that common, IMHO, or do you run into this a lot? I mean: if you create your own derived class from DataAccessAdapterBase, you get the interface IDataAccessAdapter implemented, almost all code you need and you just need to implement some abstract methods you need to have anyway.
If I'm mistaken, could you please give an example how this could be a gain? (the interfaces can be added without that much problems, it's just for myself I don't see the real gain, so I'd like to learn from you in which situations it can be a gain )
Joined: 29-Sep-2004
One example I can think of off the top of my head is that you could have for instance, the following classes implement say, IFetchTypedView:
SecureTypedView PublicTypedView
Since interfaces allow us to write swapable behavior at run-time, based on the users role/permissions, you could filter out sensitive data.
Joined: 04-Feb-2004
I like to use factories a lot of the times. Often times I use remote factories. Often times my solutions are organized into funcational areas or "subject areas" so to speak.
So, I could create objects that implement IEntityAction or ITypedViewAction in these classes to return instances of classes that only deal with entities fetches / saves and the same for typed views and collections.
For example, in my enterprise learning management system, we have a help desk component, FAQ component, CMS component, LMS admin component, etc etc etc. Each of these functional areas has domain specific questions to ask the database. Each of these areas also has its own little llblgen project, controllers, domain objects, etc. so all of these functional areas can be exposed via the TypedListActionFactory or EntityActionFactory via the interface.
This can absolutely be achieved with the current architechture in place with the existing IDataAccessAdapter / DataAccessAdapterBase, it just allows implementers more control of what they expose and "must" implement in their own derived objects.
Another example I ran across the other day was that I was using my modified manager templates (originally created by cmartinbot, that rock), and I ran into the scenario where I needed to implement typed list functionality. After reviewing the codebase, I said, well I could put the TypedListFetch methods in any of the 3 classes provided by the template generator, i.e. the ManagerBase, the DerivedEntityManagerBase, or the SealedEntityManager, or I could put it into my domain object that uses my manager factory to get a manager object. So, the first thing I did was say, ok I want to write methods to get a typed list, and I might want to do this many different ways, so I should implement all the methods provided in the DataAccessAdapterBase. Looking at this scenario, no matter where I put the methods, I still had to hand code them (which isnt bad) and I had to ensure that they conformed to the requirements of DataAccessAdapterBase. If there were an interface I could have simply implemented it and been done with it and been assured that the methods would conform to the requirements set forth by DataAccessAdapterBase..
Additional scenarios come into play with remoting, where you need a shared public interface for various entry points into a services layer. If the services layer only exposes entity fetches and save operations, we simply implement IEntityAction and boom, we are done. The methods are guaranteed to work with a real data access adapter.
I have a question about how the refactoring might work. I assume that DataAccessAdapterBase implements IDataAccessAdapter. Is it feasable to turn IDataAccessAdapter into a composite interface and still maintain backward compatibility providing that all methods exposed in IDataAccessAdapter remian intact, but they are now defined in the interfaces that IDataAccessAdapter implements?
Joined: 17-Aug-2003
Good points all, however there is a problem: .NET supports single inheritance only.
I have a question about how the refactoring might work. I assume that DataAccessAdapterBase implements IDataAccessAdapter. Is it feasable to turn IDataAccessAdapter into a composite interface and still maintain backward compatibility providing that all methods exposed in IDataAccessAdapter remian intact, but they are now defined in the interfaces that IDataAccessAdapter implements?
That's possible of course. The main thing is: you will never get rid of IDataAccessAdapter. This means that if you have a DataAccessAdapterBase derived class, it will always implement IDataAccessAdapter, and you will always be able to cast to it (cast to object, cast to the type)
The 'solution' would be (if it were possible) that every logical unit was implemented in its own subclass and that the DataAccessAdapterBase inherited from all of them. As this isn't the case, implementing the various blocks into subclasses and create DataAccessAdapterBase an aggregated host for these is not really what I want, it will clutter up the code a lot and create unnecessary property/methods to have class interaction.
So to have a class derive from DataAccessAdapterBase just to have for example TypedList code, is not possible as that code is already implemented in that base class, as well as all other code.
Another option would be to have some sort of unlock system for functionality but thats also breakable with invoking private members. So I'm not sure what the interfaces would bring you, unless you don't really care for the casting loophole that is
Joined: 29-Sep-2004
Devildog74 wrote:
For example, in my enterprise learning management system, we have a help desk component, FAQ component, CMS component, LMS admin component, etc etc etc. Each of these functional areas has domain specific questions to ask the database. Each of these areas also has its own little llblgen project, controllers, domain objects, etc. so all of these functional areas can be exposed via the TypedListActionFactory or EntityActionFactory via the interface.
I am one of the developers on a workers compensation application, and we have one database and we split out application (UI) up into 3 distinct area: Operations, Sales, and Technical. I was wondering if in your example you mentioned above, would you take what I just described and create three seperate projects, since they are the functional areas, even though they are tied back to the same database? For example, I could have something like the following:
Business.Operations.Controllers Business.Operations.Reporting Business.Operations.Data < ---- LLBL DBSpecific and DBGeneric projects
I'm just looking for any ideas or thoughts to help me think outside the box.
Thanks
Joined: 04-Feb-2004
Yes, I would have 3 seperate solutions, one for each functional area. And, if your organization is big enough, you might just have teams of specialists that are familiar with just the requirements and codebase for each of the functional areas.
From a business standpoint, youre almost guaranteed to have product specialists / product champions that are intimate with the UI requirments and business requirements of these 3 vertical segments of the application.
If youre not that big, then it would still help organize huge projects IMO.
Some could argue that more assemblies means more moving parts, but I argue that this approach isolates change to just the functional area and makes deployment easier.
Joined: 29-Sep-2004
Devildog74 wrote:
Yes, I would have 3 seperate solutions, one for each functional area. And, if your organization is big enough, you might just have teams of specialists that are familiar with just the requirements and codebase for each of the functional areas.
From a business standpoint, youre almost guaranteed to have product specialists / product champions that are intimate with the UI requirments and business requirements of these 3 vertical segments of the application.
If youre not that big, then it would still help organize huge projects IMO.
Some could argue that more assemblies means more moving parts, but I argue that this approach isolates change to just the functional area and makes deployment easier.
When you say three solutions, are you referring to three seperate applications?
Joined: 04-Feb-2004
I would have 3 seperate .sln files that pulled together all required projects related to the functional area in question.
If the application is one big windows forms application, I would implement the 3 functional areas as plugins, and my plugin project would just be a framework to tie together the 3 functional areas. So, when the main app starts, if the plugin for only 2 functional areas exist, the user would only get menu options for the 2 plugins installed. You could also install all the plugins, and make then security context sensitive. Does this make any sense?
Joined: 29-Sep-2004
Devildog74 wrote:
I would have 3 seperate .sln files that pulled together all required projects related to the functional area in question.
If the application is one big windows forms application, I would implement the 3 functional areas as plugins, and my plugin project would just be a framework to tie together the 3 functional areas. So, when the main app starts, if the plugin for only 2 functional areas exist, the user would only get menu options for the 2 plugins installed. You could also install all the plugins, and make then security context sensitive. Does this make any sense?
Ok, this is making more sense now. So, would each functional area solution contain its own .exe file and the main app would fire this guy off?
Joined: 04-Feb-2004
Each functional area would contain a primary dll that would be the main entry point for the plugin. The primary exe, which would just be an mdi form, would load up all of the dlls for each of the functional areas, inspect the dlls and then render the main menu accordingly.
The link below shows a very simplistic approach, but the basic concept is there.
http://www.thecodeproject.com/csharp/C__Plugin_Architecture.asp