-
Notifications
You must be signed in to change notification settings - Fork 3.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How to resolve DbContext in package-by-feature or other "vertical slice" architectures? #26447
Comments
Related to (possibly dup of) #16470.
Am not familiar with this architecture - can you point to a resource detailing the advantages of separating out to different assemblies like this? |
I'm not sure how this was concluded. Other than DI being a marginally shared theme, and my involvement in that thread. Not once in this post did I make mention of interfaces for EF Core classes. I thought I clearly explain the problem space, maybe I didn't, where is the ambiguity? Edit:
I wouldn't say it's my place to justify the architecture, I'm neither an expert on it, nor an advocate. It's an architecture I'm exploring and finding out that EF Core's rigidity to various architectural patterns (Mainly in where they end up converging on a reliance on Dependency Inversion, the My grumbling aside though: Assuming you are already marginally familiar with the advantages of vertical-slice/x-by-feature architecture, Domain Driven Design, and maybe even CQRS. Generally
Though to be clear, I don't want this to be a discussion on the merits or demerits of various architectural patterns, these have been explored in exhaustive detail in various books, blogs, and boards already. And exist in real-world applications, libraries, toolsets, and implementations Why am I even making this post? I was exploring this sort of architecture when EF Core pumped the breaks on a foundational aspect of it, DI. Given this isn't the first time I've found EF Core to be a hindrance in this way, a way it's sibling projects actively encourage and promote, decided to make an issue about it since it's getting ridiculous at this point. Written to try and make more clear the problem caused by this. My objective is to open up a real discussion on the problem. Not one that gets shutdown by someone running on the platform of "I don't understand the problem space, therefore it's not a valid problem". Which is frustrating, to say the least, especially when real effort is put into these posts/comments. The problem of not being able to invert entity dependencies with EF Core is a real problem that affects things on a very abstract level, which can make it difficult to "get" for many. The gist of it being that many design & architectural options that are used in applications stop being available here. Preemptively addressing questions along the lines of This is a red herring, intentional or not, that moves the discussion from a problem & solution, to one of endless justification & retort. That requires a significant depth of knowledge to answer well, and no depth to keep endlessly prodding without investing energy into understanding. Why is it difficult to describe/answer re: patterns & architecture?
|
Sorry for the long post, I'm being sincere here, and hope you will be too. |
A brief example of a conversation I had recently (With someone about feature-packages) that further highlights the problem space.
Solving problems in this manner is commonplace, but the moment you consider doing this with your entities, you suddenly have an awkward situation. You can no longer apply a common solution to a common problem. |
@douglasg14b I think it would help us understand what it is you are looking for if we could see something a bit more concrete. Two possibilities for this are:
Would it be possible to provide one or both of these things? |
I can do that! I'm kinda hammered right now, so it will take a bit of time to circle back around to this. Thank you for both the response, and your patience. As for the 2nd request though, that gets difficult as I only know of proprietary ones (From current and past employers and clients). The best I could suggest is reading material, a quick google search on |
@douglasg14b sure thing, and thanks for your time on this. FWIW my comment above wasn't meant to cast doubt or to ask you to justify anything - just curiosity about the pattern and a desire to know more. In any case, a simple skeleton solution would go a long way to help us understand exactly what's being requested and how we can help address it from the EF Core side. |
I think I know what you mean, but I found solution that works for splitting entities between packages, but still having just one DbContext in the main application. Note that DbSet property is not required for querying anymore, you can just add the entities with Fluent API: In feature package: public class Thing
{
public Guid Id { get; set; }
public string Name { get; set; } = "";
}
public class Other
{
public Guid Id { get; set; }
public string Name { get; set; } = "";
}
public static class ModelBuilderExtension {
public static void AddMyStuff(this ModelBuilder modelBuilder)
{
modelBuilder.Entity<Thing>(); // Notice that DbSet is not required!
modelBuilder.Entity<Other>();
}
} In main app package: public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.AddMyStuff(); // <-- This registers the entities
base.OnModelCreating(modelBuilder);
}
} You can even make Repositories in the feature package if you make a decision e.g. to register AppDbContext as a DbContext service. Notice that you don't need the DbSet as properties to make queries, adding or changing the entities: dbContext.Add(new Thing() {
Name = "Foo"
});
dbContext.SaveChanges();
dbContext.Set<Thing>().Where(p => p.Name == "Foo").First(); In above the |
EF Team Triage: Closing this issue as the requested additional details have not been provided and we have been unable to reproduce it. BTW this is a canned response and may have info or details that do not directly apply to this particular issue. While we'd like to spend the time to uniquely address every incoming issue, we get a lot traffic on the EF projects and that is not practical. To ensure we maximize the time we have to work on fixing bugs, implementing new features, etc. we use canned responses for common triage decisions. |
Preface
Similar to
feature-folder
architecture,package-by-feature
vertically slices the codebase to achieve much better cohesion, However, EF Core seems to get right in the way of that since aDbSet
can only be of a concrete type, and we can't really "register" our entities in a non-coupled fashion.This is one (of many) long-standing architectures (This one articled/ written on circa ~2005 by "Uncle Bob") that are relatively easy to use with Asp.Net Core, but sibling projects seems to produce difficulties.
Can EF Core work in a vertically sliced application where the slices are assemblies without forcing the application to break from it's architecture?
Include your code
Say you have this structure, each feature is a different project/assembly.:
Each feature entity is a DDD styled aggregate, so it is self-contained and defends its own invariants, as opposed to it simply being a POCO.
Each feature service needs a
DbContext
and may want access to load entities from another feature. However, there is no way to define a "shared" DbContext without creating an assembly that is a circular-reference. An outside assembly would need to reference each feature assembly to use theFeature
in each of the context's the DbSet, and each assembly would then need to reference that assembly to use that
DbContext`This could be solved in a few ways:
I imagine I'm missing some feature/aspect of EF Core that enables this. How can EF Core work with this sort of architecture?
The text was updated successfully, but these errors were encountered: