dotnet / efcore

EF Core is a modern object-database mapper for .NET. It supports LINQ queries, change tracking, updates, and schema migrations.
https://docs.microsoft.com/ef/
MIT License
13.61k stars 3.14k forks source link

Add API to configure construction of entity type instances #10789

Open ajcvickers opened 6 years ago

ajcvickers commented 6 years ago

Issue #10703 covered the ability of EF to call a parameterized constructor. However, the constructor to use is not configurable. This issue is about adding fluent API and/or annotations to do this and also:

todd-skelton commented 6 years ago

Is there any workaround to prevent parameterized constructors from being used until it's configurable? I have creation events in my constructors and they are getting raised every time the objects are queried.

ajcvickers commented 6 years ago

@xKloc Starting with preview2, if there are both parameterized and empty constructors, then EF will choose the empty one. See #10852

adrianiftode commented 5 years ago

There is a note in the documentation of the Entity types with constructors section that as some point the following feature will be implemented:

As of EF Core 2.1, only services known by EF Core can be injected. Support for injecting application services is being considered for a future release.

Is this issue tracking this feature?

One of my use cases would be to have the ability to publish some interesting events that happen within an entity

public class Blog
{
    private readonly IMediator _mediator;
    private int _id;

    public Blog(string name, string author, IMediator mediator)
    {
        Name = name;
        Author = author;
        _mediator = mediator;
    }

    public async Task AddPost(string content)
    {
           this.Posts.Add(new Post(content));
           if (this.Posts.Count > PostsLimit)
           {
                 await _mediator.Publish(new MaximumBlogPostsReached(_id);
           }
    }
}
thomasdc commented 4 years ago

Support for ctor injecting an ILogger in domain entities would be a great addition.

AndriySvyryd commented 4 years ago

@thomasdc You can do that already!

ajcvickers commented 4 years ago

@AndriySvyryd Not sure it would be easy to do this with the API surface we have now. But it's a nice idea--maybe I'll add it as one of the built-in services we support.

ajcvickers commented 4 years ago

@AndriySvyryd @thomasdc Filed #20203

cesarsouza commented 4 years ago

Wouldn't it be possible to allow injecting IServiceProvider and therefore make all services available to be grabbed by the entities?

Sure it sounds like a potential to apply many anti-patterns but the decision to use it could be left up to the user.

frankbuckley commented 1 year ago

Would love to see something like:

modelBuilder.Entity<Blog>().HasConstructor((string name, string author) => Blog.Create(name, author));

In the meantime, a NotMapped/Ignore attribute or a MappedConstructor attribute might be a quick win to avoid awkward workarounds for constructor selection.