I'm working on a composite total system application which different companies may add different modules but there is only one database.I have a Generic repository in my framework which is technology independent (I mean it's provider base and for now the defult provider is EF 4.1 ).I have seprated common layer which contains poco entities and there is also different entities per module in their own assemblies. Now the problem is the entities mapping.I don't have any access to my entities from my EF provider project as I don't know the future modules ! so how can I map my entities in a generic approach? Is it possible?
One solution that I think is having a config file and adding entities FullName then ieterating and reflecting each one and then I can add them in OnModelCreat(...) method but ofcourse there is some performance concerns.
Edit: Firstly thanks for your reply Ladislav. But there is some more info for you.
You can make a requirement that each module must contain mapping classes for every new entity it uses. When you start the application you will just use reflection to get all classes derived from StructuralTypeConfiguration<> (includes both entities and complex types), create instances of these types and add them to Configurations collection in DbModelBuilder (can be done in OnModelCreating).
It will take some time but it will happens only once when context is used for the first time. You can trigger this creation during application start - applications simply need some time to start and configure all infrastructure they need to use.
Edit:
I have to reference EntityFramework.dll in every module which is not suitable in this case.
Yes. You want to allow other developers to define their own entities which will be persisted by your core application. In such case they must use your persistence framework of choice to tell your application how to persist their entities.
==> as I mentioned before, EF is not my only DataProvider ! I have to have some other DP such as a dataprovider for DB4O and etc so I don't want to reference each provider's dependencies to each module ... therefore I need to encapsulate EF in a separate assembly
If you use repositories each module should even contain its own repositories for working with its own entities - generic repository doesn't exists. Generic repository is redundant useless layer which only makes work with ORM of your choice much harder. To make it clear - correct implementation of repository pattern is not generic. It is specific and it expose data access functionality for single entity or aggregate root.
==> may I ask for any reliable ref ?! Why should I add one repository per module in case only one repository can do all of my requirements? which is redundant ? In my oppenion using specific or generic rep are both correct in a correct situation.90% of my modules has same requirements from a repository and all of them should have CRUD ...
If you don't want EF dependency in modules either don't use EF at all or define your own intermediate mapping layer which will be converted to specific mapping in your application - a lot of work with zero added value.
==> In fact I'm trying to define my own mapping layer because I need it in my app architecture.it is not useless for me.This was the only reason that I asked how to implement it.I'm looking for the best solution and I hope you could help me to hand on it :)
Other option is simply not allowing your modules to use new entities because it looks more like your current expectation. If module developer must define new database tables for his entities he must also be able to work with persistence and define mapping between tables and his entities.
==> Good Idea but not suitable for my case ;)
I have to reflect each module dll at startup which means lots of heavy dll's to be reflected and ... is there any other Idea?
Have you ever seen applications like Photoshop, Visual Studio or even MS Office applications during their startup? What do you think is happening when you see splash screen? Application is initializing - it is loading and initializing its features and plugins. Even server application can need minutes to be fully started. You are building modular application (not composite) so you must pay for that requirement.
==> Yeah I think I saw some of them ! If they are loading for example all the pallets or sidebars at startup they have to employ me .Hey dear microsoft if you don't know what is the defer loading I can help you to improve your performance :)
If you don't want to use reflection yourselves you can use MEF for building modularized infrastructure.
==>I'm already using Prism and MEF for handling modularity but only for modules not for my providers...
It sounds that EF is not a good solution for enterprise composite app right?
You didn't propose any enterprise requirement that shouldn't be fulfilled by EF. You just fights with your expectations to allow module developers to use new entities but don't give them ability to describe how these entities will be persisted - but who will describe it?
==> A model or a intermediate mapper layer which will work in each module load and map the entities if the EF support (which can't as I know) I need something like bootstrapper for each provider to map the entities :)
You are not building composite application. Composite application takes existing functionality (components, existing applications) which works separately and composite them to a new application. You are building modular application where your core can host another modules but those modules cannot run without your hosting infrastructure.
==>I'm not going to give lecture about my app and its architecture but I think just this much is enough that you know this is a composite/modular application ...
Should I switch to Model First?!!
Model first (and EDMX generally) is really not suitable for your expectations because in case of model first each module will need its own EDMX file and its own context.
==> but I can change the model and the xml of EDMX file at runtime right?!
You also mustn't use automatic database generation by code first because any new module will either break your application or EF will delete your current database.
==> thanks for this advice although I knew it before but ofcourse I will give more attention to it.