Using ef4 code first you can create and compile classes and dbcontext. What happens when you want to add some classes/tables and relationships in an already compiled dll of a model set?
So far the solutions I have come up with are using "partial" classes, that would be complimented later on, and the second one is writing a whole new dbcontext that includes the first one in some way or extending it, but this would mean additional db connection per module (per db context). Any ideas about this? What's the best practice ? Also I need to be able to work with migrations.
More explicitly, a possible scenario is as follows:
A) You create a .dll with some dbContextBase class and tables(classes) inside that.
B) You create other .dlls that depend/extend dbContextBase in their own way*
C) You refference said .dlls in a project and extend them.
So basically you can have a core dbContext, then add a menu module to it, then you add a blog module to it (but it can be seen by the Menu module in order to create latest blog posts menus etc). On top of that, if you want a specific one-time feature for blog you can quickly integrate that, but also keep your blog module updateable.
As I beggin to see it the best way to do that is Nuget packages with the source code for the models (and the like) per module, instead of compiled dll.
As clear from the figure, the entity framework creates or updates the database depending upon the domain classes. Hence, the user needs to code first, and then the entity framework will create the database using the code. That is why it is called the code first approach.
EF Core Development Approaches In the code-first approach, EF Core API creates the database and tables using migration based on the conventions and configuration provided in your domain classes. This approach is useful in Domain Driven Design (DDD).
As with any code-first schema customization, you can do this by using the entity classes' attributes or through the DbModelBuilder API. With data annotations, you can use the optional second parameter of the Table attribute to specify the schema name. The code in Figure 3 implements this change in the model.
EF code first Provides a set of data annotation attributes, which we can apply to our domain classes and properties. DataAnnotation attributes override default code-first conventions. You can find most of the attributes in System. ComponentModel. DataAnnotations namespace.
You can build some infrastructure in your core assemblies which will discover entities in your modules and register them to single context. Each entity must have class derived from EntityTypeConfiguration<>
(or ComplexTypeConfiguration<>
for complex types) which will describe the mapping.
Once you have mapping classes you can either use some module interface to collect all of them for every module or use reflection to browse assemblies and create instances of mapping classes. These classes can be either use in by DbModelBuilder
directly (either in OnModelCreating
or directly).
Also I need to be able to work with migrations.
I'm not sure if migrations are ready for this because it has some preconditions:
DbMigration
derived class (or classes for new versions)DbMigration
derived class (or classes for new versions)It means that you have special migration set for core and one migration set for every module. Every migration set is defined in separate assembly - this can be potential problem. I didn't try it myself so I don't know if EF migrations can handle this - I especially target scenarios where you really want modular systems where modules can be added or removed over time so you need both installation (Up
method) and uninstallation (Down
method).
The problem with migrations is that you cannot for those must and mustn't so if you develop the platform where people can add custom modules you never know if they don't break your core.
Since there is no answer that focuses on the problem the way I put it, I am posting an answer with what seems to be the best workaround at this moment.
For full support of migrations, even custom migrations, and full support in general for code-first design, the best method is to import the source codes and compile directly.
We are using a local nuget feed in order to be able to sync multiple sub-modules freely and swiftly. This also leads to a good update experience since the migrations can easily be created or imported/integrated when needed
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With