Skip to content
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

Support DI for contructors of POCO #3342

Open
Tracked by #240
Artur2 opened this issue Oct 6, 2015 · 10 comments
Open
Tracked by #240

Support DI for contructors of POCO #3342

Artur2 opened this issue Oct 6, 2015 · 10 comments

Comments

@Artur2
Copy link

Artur2 commented Oct 6, 2015

Hello EF Development team.
I have a question about dependency injection.
Does EF looking for dependencies when materializing object from database in this manner ?

public class Person 
{

   public Person(DataContext context)
   {
    ....
   }

   // or maybe like this
   [Dependency]
   public DataContext Context {get;set;}
}

After loading and materializing from database DataContext(DataContext is inherited from DbContext) must injected in constructor.

Anything like this is possible now ?

@Artur2
Copy link
Author

Artur2 commented Oct 8, 2015

@bricelam , @rowanmiller ?

@divega
Copy link
Contributor

divega commented Oct 8, 2015

We currently don't support this, but it is one of the capabilities for flexible object mapping (#240) we will consider adding in the future.

@Artur2
Copy link
Author

Artur2 commented Oct 8, 2015

@divega thank you for answer =)

@rowanmiller
Copy link
Contributor

This work is covered by #240

@divega
Copy link
Contributor

divega commented Jun 3, 2017

Reopening to prioritize separately from the main flexible mapping issue.

@divega divega reopened this Jun 3, 2017
@divega divega added this to the Backlog milestone Jun 3, 2017
ajcvickers added a commit that referenced this issue Dec 31, 2017
Parts of issues #3342, #240, #10509, #3797

The main things here are:
- Support for injecting values into parameterized entity constructors
  - Property values are injected if the parameter type and name matches
  - The current DbContext as DbContext or a derived DbContext type
  - A service from the internal or external service provider
  - A delegate to a method of a service
- Use of the above to inject lazy loading capabilities into entities

For lazy loading, either the ILazyLoader service can be injected directly, or a delegate can be injected if the entity class cannot take a dependency on the EF assembly--see the examples below.

Currently all constructor injection is done by convention.

Remaining work includes:
- API/attributes to configure the constructor binding
- Allow factory to be used instead of using the constructor directly. (Functional already, but no API or convention to configure it.)
- Allow property injection for services
- Configuration of which entities/properties should be lazy loaded and which should not

### Examples

In this example EF will use the private constructor passing in values from the database when creating entity instances. (Note that it is assumed that _blogId has been configured as the key.)

```C#
public class Blog
{
    private int _blogId;

    // This constructor used by EF Core
    private Blog(
        int blogId,
        string title,
        int? monthlyRevenue)
    {
        _blogId = blogId;
        Title = title;
        MonthlyRevenue = monthlyRevenue;
    }

    public Blog(
        string title,
        int? monthlyRevenue = null)
        : this(0, title, monthlyRevenue)
    {
    }

    public string Title { get; }
    public int? MonthlyRevenue { get; set; }
}
```

In this example, EF will inject the ILazyLoader instance, which is then used to enable lazy-loading on navigation properties. Note that the navigation properties must have backing fields and all access by EF will go through the backing fields to prevent EF triggering lazy loading itself.

```C#
public class LazyBlog
{
    private readonly ILazyLoader _loader;
    private ICollection<LazyPost> _lazyPosts = new List<LazyPost>();

    public LazyBlog()
    {
    }

    private LazyBlog(ILazyLoader loader)
    {
        _loader = loader;
    }

    public int Id { get; set; }

    public ICollection<LazyPost> LazyPosts
        => _loader.Load(this, ref _lazyPosts);
}

public class LazyPost
{
    private readonly ILazyLoader _loader;
    private LazyBlog _lazyBlog;

    public LazyPost()
    {
    }

    private LazyPost(ILazyLoader loader)
    {
        _loader = loader;
    }

    public int Id { get; set; }

    public LazyBlog LazyBlog
    {
        get => _loader.Load(this, ref _lazyBlog);
        set => _lazyBlog = value;
    }
}
```

This example is the same as the last example, except EF is matching the delegate type and parameter name and injecting a delegate for the ILazyLoader.Load method so that the entity class does not need to reference the EF assembly. A small extension method can be included in the entity assembly to make it a bit easier to use the delegate.

```C#
public class LazyPocoBlog
{
    private readonly Action<object, string> _loader;
    private ICollection<LazyPocoPost> _lazyPocoPosts = new List<LazyPocoPost>();

    public LazyPocoBlog()
    {
    }

    private LazyPocoBlog(Action<object, string> lazyLoader)
    {
        _loader = lazyLoader;
    }

    public int Id { get; set; }

    public ICollection<LazyPocoPost> LazyPocoPosts
        => _loader.Load(this, ref _lazyPocoPosts);
}

public class LazyPocoPost
{
    private readonly Action<object, string> _loader;
    private LazyPocoBlog _lazyPocoBlog;

    public LazyPocoPost()
    {
    }

    private LazyPocoPost(Action<object, string> lazyLoader)
    {
        _loader = lazyLoader;
    }

    public int Id { get; set; }

    public LazyPocoBlog LazyPocoBlog
    {
        get => _loader.Load(this, ref _lazyPocoBlog);
        set => _lazyPocoBlog = value;
    }
}

public static class TestPocoLoadingExtensions
{
    public static TRelated Load<TRelated>(
        this Action<object, string> loader,
        object entity,
        ref TRelated navigationField,
        [CallerMemberName] string navigationName = null)
        where TRelated : class
    {
        loader?.Invoke(entity, navigationName);

        return navigationField;
    }
}
```
ajcvickers added a commit that referenced this issue Jan 1, 2018
Parts of issues #3342, #240, #10509, #3797

The main things here are:
- Support for injecting values into parameterized entity constructors
  - Property values are injected if the parameter type and name matches
  - The current DbContext as DbContext or a derived DbContext type
  - A service from the internal or external service provider
  - A delegate to a method of a service
- Use of the above to inject lazy loading capabilities into entities

For lazy loading, either the ILazyLoader service can be injected directly, or a delegate can be injected if the entity class cannot take a dependency on the EF assembly--see the examples below.

Currently all constructor injection is done by convention.

Remaining work includes:
- API/attributes to configure the constructor binding
- Allow factory to be used instead of using the constructor directly. (Functional already, but no API or convention to configure it.)
- Allow property injection for services
- Configuration of which entities/properties should be lazy loaded and which should not

### Examples

In this example EF will use the private constructor passing in values from the database when creating entity instances. (Note that it is assumed that _blogId has been configured as the key.)

```C#
public class Blog
{
    private int _blogId;

    // This constructor used by EF Core
    private Blog(
        int blogId,
        string title,
        int? monthlyRevenue)
    {
        _blogId = blogId;
        Title = title;
        MonthlyRevenue = monthlyRevenue;
    }

    public Blog(
        string title,
        int? monthlyRevenue = null)
        : this(0, title, monthlyRevenue)
    {
    }

    public string Title { get; }
    public int? MonthlyRevenue { get; set; }
}
```

In this example, EF will inject the ILazyLoader instance, which is then used to enable lazy-loading on navigation properties. Note that the navigation properties must have backing fields and all access by EF will go through the backing fields to prevent EF triggering lazy loading itself.

```C#
public class LazyBlog
{
    private readonly ILazyLoader _loader;
    private ICollection<LazyPost> _lazyPosts = new List<LazyPost>();

    public LazyBlog()
    {
    }

    private LazyBlog(ILazyLoader loader)
    {
        _loader = loader;
    }

    public int Id { get; set; }

    public ICollection<LazyPost> LazyPosts
        => _loader.Load(this, ref _lazyPosts);
}

public class LazyPost
{
    private readonly ILazyLoader _loader;
    private LazyBlog _lazyBlog;

    public LazyPost()
    {
    }

    private LazyPost(ILazyLoader loader)
    {
        _loader = loader;
    }

    public int Id { get; set; }

    public LazyBlog LazyBlog
    {
        get => _loader.Load(this, ref _lazyBlog);
        set => _lazyBlog = value;
    }
}
```

This example is the same as the last example, except EF is matching the delegate type and parameter name and injecting a delegate for the ILazyLoader.Load method so that the entity class does not need to reference the EF assembly. A small extension method can be included in the entity assembly to make it a bit easier to use the delegate.

```C#
public class LazyPocoBlog
{
    private readonly Action<object, string> _loader;
    private ICollection<LazyPocoPost> _lazyPocoPosts = new List<LazyPocoPost>();

    public LazyPocoBlog()
    {
    }

    private LazyPocoBlog(Action<object, string> lazyLoader)
    {
        _loader = lazyLoader;
    }

    public int Id { get; set; }

    public ICollection<LazyPocoPost> LazyPocoPosts
        => _loader.Load(this, ref _lazyPocoPosts);
}

public class LazyPocoPost
{
    private readonly Action<object, string> _loader;
    private LazyPocoBlog _lazyPocoBlog;

    public LazyPocoPost()
    {
    }

    private LazyPocoPost(Action<object, string> lazyLoader)
    {
        _loader = lazyLoader;
    }

    public int Id { get; set; }

    public LazyPocoBlog LazyPocoBlog
    {
        get => _loader.Load(this, ref _lazyPocoBlog);
        set => _lazyPocoBlog = value;
    }
}

public static class TestPocoLoadingExtensions
{
    public static TRelated Load<TRelated>(
        this Action<object, string> loader,
        object entity,
        ref TRelated navigationField,
        [CallerMemberName] string navigationName = null)
        where TRelated : class
    {
        loader?.Invoke(entity, navigationName);

        return navigationField;
    }
}
```
ajcvickers added a commit that referenced this issue Jan 2, 2018
Parts of issues #3342, #240, #10509, #3797

The main things here are:
- Support for injecting values into parameterized entity constructors
  - Property values are injected if the parameter type and name matches
  - The current DbContext as DbContext or a derived DbContext type
  - A service from the internal or external service provider
  - A delegate to a method of a service
  - The IEntityType for the entity
- Use of the above to inject lazy loading capabilities into entities

For lazy loading, either the ILazyLoader service can be injected directly, or a delegate can be injected if the entity class cannot take a dependency on the EF assembly--see the examples below.

Currently all constructor injection is done by convention.

Remaining work includes:
- API/attributes to configure the constructor binding
- Allow factory to be used instead of using the constructor directly. (Functional already, but no API or convention to configure it.)
- Allow property injection for services
- Configuration of which entities/properties should be lazy loaded and which should not

### Examples

In this example EF will use the private constructor passing in values from the database when creating entity instances. (Note that it is assumed that _blogId has been configured as the key.)

```C#
public class Blog
{
    private int _blogId;

    // This constructor used by EF Core
    private Blog(
        int blogId,
        string title,
        int? monthlyRevenue)
    {
        _blogId = blogId;
        Title = title;
        MonthlyRevenue = monthlyRevenue;
    }

    public Blog(
        string title,
        int? monthlyRevenue = null)
        : this(0, title, monthlyRevenue)
    {
    }

    public string Title { get; }
    public int? MonthlyRevenue { get; set; }
}
```

In this example, EF will inject the ILazyLoader instance, which is then used to enable lazy-loading on navigation properties. Note that the navigation properties must have backing fields and all access by EF will go through the backing fields to prevent EF triggering lazy loading itself.

```C#
public class LazyBlog
{
    private readonly ILazyLoader _loader;
    private ICollection<LazyPost> _lazyPosts = new List<LazyPost>();

    public LazyBlog()
    {
    }

    private LazyBlog(ILazyLoader loader)
    {
        _loader = loader;
    }

    public int Id { get; set; }

    public ICollection<LazyPost> LazyPosts
        => _loader.Load(this, ref _lazyPosts);
}

public class LazyPost
{
    private readonly ILazyLoader _loader;
    private LazyBlog _lazyBlog;

    public LazyPost()
    {
    }

    private LazyPost(ILazyLoader loader)
    {
        _loader = loader;
    }

    public int Id { get; set; }

    public LazyBlog LazyBlog
    {
        get => _loader.Load(this, ref _lazyBlog);
        set => _lazyBlog = value;
    }
}
```

This example is the same as the last example, except EF is matching the delegate type and parameter name and injecting a delegate for the ILazyLoader.Load method so that the entity class does not need to reference the EF assembly. A small extension method can be included in the entity assembly to make it a bit easier to use the delegate.

```C#
public class LazyPocoBlog
{
    private readonly Action<object, string> _loader;
    private ICollection<LazyPocoPost> _lazyPocoPosts = new List<LazyPocoPost>();

    public LazyPocoBlog()
    {
    }

    private LazyPocoBlog(Action<object, string> lazyLoader)
    {
        _loader = lazyLoader;
    }

    public int Id { get; set; }

    public ICollection<LazyPocoPost> LazyPocoPosts
        => _loader.Load(this, ref _lazyPocoPosts);
}

public class LazyPocoPost
{
    private readonly Action<object, string> _loader;
    private LazyPocoBlog _lazyPocoBlog;

    public LazyPocoPost()
    {
    }

    private LazyPocoPost(Action<object, string> lazyLoader)
    {
        _loader = lazyLoader;
    }

    public int Id { get; set; }

    public LazyPocoBlog LazyPocoBlog
    {
        get => _loader.Load(this, ref _lazyPocoBlog);
        set => _lazyPocoBlog = value;
    }
}

public static class TestPocoLoadingExtensions
{
    public static TRelated Load<TRelated>(
        this Action<object, string> loader,
        object entity,
        ref TRelated navigationField,
        [CallerMemberName] string navigationName = null)
        where TRelated : class
    {
        loader?.Invoke(entity, navigationName);

        return navigationField;
    }
}
```
ajcvickers added a commit that referenced this issue Jan 2, 2018
Parts of issues #3342, #240, #10509, #3797

The main things here are:
- Support for injecting values into parameterized entity constructors
  - Property values are injected if the parameter type and name matches
  - The current DbContext as DbContext or a derived DbContext type
  - A service from the internal or external service provider
  - A delegate to a method of a service
  - The IEntityType for the entity
- Use of the above to inject lazy loading capabilities into entities

For lazy loading, either the ILazyLoader service can be injected directly, or a delegate can be injected if the entity class cannot take a dependency on the EF assembly--see the examples below.

Currently all constructor injection is done by convention.

Remaining work includes:
- API/attributes to configure the constructor binding
- Allow factory to be used instead of using the constructor directly. (Functional already, but no API or convention to configure it.)
- Allow property injection for services
- Configuration of which entities/properties should be lazy loaded and which should not

### Examples

In this example EF will use the private constructor passing in values from the database when creating entity instances. (Note that it is assumed that _blogId has been configured as the key.)

```C#
public class Blog
{
    private int _blogId;

    // This constructor used by EF Core
    private Blog(
        int blogId,
        string title,
        int? monthlyRevenue)
    {
        _blogId = blogId;
        Title = title;
        MonthlyRevenue = monthlyRevenue;
    }

    public Blog(
        string title,
        int? monthlyRevenue = null)
        : this(0, title, monthlyRevenue)
    {
    }

    public string Title { get; }
    public int? MonthlyRevenue { get; set; }
}
```

In this example, EF will inject the ILazyLoader instance, which is then used to enable lazy-loading on navigation properties. Note that the navigation properties must have backing fields and all access by EF will go through the backing fields to prevent EF triggering lazy loading itself.

```C#
public class LazyBlog
{
    private readonly ILazyLoader _loader;
    private ICollection<LazyPost> _lazyPosts = new List<LazyPost>();

    public LazyBlog()
    {
    }

    private LazyBlog(ILazyLoader loader)
    {
        _loader = loader;
    }

    public int Id { get; set; }

    public ICollection<LazyPost> LazyPosts
        => _loader.Load(this, ref _lazyPosts);
}

public class LazyPost
{
    private readonly ILazyLoader _loader;
    private LazyBlog _lazyBlog;

    public LazyPost()
    {
    }

    private LazyPost(ILazyLoader loader)
    {
        _loader = loader;
    }

    public int Id { get; set; }

    public LazyBlog LazyBlog
    {
        get => _loader.Load(this, ref _lazyBlog);
        set => _lazyBlog = value;
    }
}
```

This example is the same as the last example, except EF is matching the delegate type and parameter name and injecting a delegate for the ILazyLoader.Load method so that the entity class does not need to reference the EF assembly. A small extension method can be included in the entity assembly to make it a bit easier to use the delegate.

```C#
public class LazyPocoBlog
{
    private readonly Action<object, string> _loader;
    private ICollection<LazyPocoPost> _lazyPocoPosts = new List<LazyPocoPost>();

    public LazyPocoBlog()
    {
    }

    private LazyPocoBlog(Action<object, string> lazyLoader)
    {
        _loader = lazyLoader;
    }

    public int Id { get; set; }

    public ICollection<LazyPocoPost> LazyPocoPosts
        => _loader.Load(this, ref _lazyPocoPosts);
}

public class LazyPocoPost
{
    private readonly Action<object, string> _loader;
    private LazyPocoBlog _lazyPocoBlog;

    public LazyPocoPost()
    {
    }

    private LazyPocoPost(Action<object, string> lazyLoader)
    {
        _loader = lazyLoader;
    }

    public int Id { get; set; }

    public LazyPocoBlog LazyPocoBlog
    {
        get => _loader.Load(this, ref _lazyPocoBlog);
        set => _lazyPocoBlog = value;
    }
}

public static class TestPocoLoadingExtensions
{
    public static TRelated Load<TRelated>(
        this Action<object, string> loader,
        object entity,
        ref TRelated navigationField,
        [CallerMemberName] string navigationName = null)
        where TRelated : class
    {
        loader?.Invoke(entity, navigationName);

        return navigationField;
    }
}
```
ajcvickers added a commit that referenced this issue Jan 3, 2018
Parts of issues #3342, #240, #10509, #3797

The main things here are:
- Support for injecting values into parameterized entity constructors
  - Property values are injected if the parameter type and name matches
  - The current DbContext as DbContext or a derived DbContext type
  - A service from the internal or external service provider
  - A delegate to a method of a service
  - The IEntityType for the entity
- Use of the above to inject lazy loading capabilities into entities

For lazy loading, either the ILazyLoader service can be injected directly, or a delegate can be injected if the entity class cannot take a dependency on the EF assembly--see the examples below.

Currently all constructor injection is done by convention.

Remaining work includes:
- API/attributes to configure the constructor binding
- Allow factory to be used instead of using the constructor directly. (Functional already, but no API or convention to configure it.)
- Allow property injection for services
- Configuration of which entities/properties should be lazy loaded and which should not

### Examples

In this example EF will use the private constructor passing in values from the database when creating entity instances. (Note that it is assumed that _blogId has been configured as the key.)

```C#
public class Blog
{
    private int _blogId;

    // This constructor used by EF Core
    private Blog(
        int blogId,
        string title,
        int? monthlyRevenue)
    {
        _blogId = blogId;
        Title = title;
        MonthlyRevenue = monthlyRevenue;
    }

    public Blog(
        string title,
        int? monthlyRevenue = null)
        : this(0, title, monthlyRevenue)
    {
    }

    public string Title { get; }
    public int? MonthlyRevenue { get; set; }
}
```

In this example, EF will inject the ILazyLoader instance, which is then used to enable lazy-loading on navigation properties. Note that the navigation properties must have backing fields and all access by EF will go through the backing fields to prevent EF triggering lazy loading itself.

```C#
public class LazyBlog
{
    private readonly ILazyLoader _loader;
    private ICollection<LazyPost> _lazyPosts = new List<LazyPost>();

    public LazyBlog()
    {
    }

    private LazyBlog(ILazyLoader loader)
    {
        _loader = loader;
    }

    public int Id { get; set; }

    public ICollection<LazyPost> LazyPosts
        => _loader.Load(this, ref _lazyPosts);
}

public class LazyPost
{
    private readonly ILazyLoader _loader;
    private LazyBlog _lazyBlog;

    public LazyPost()
    {
    }

    private LazyPost(ILazyLoader loader)
    {
        _loader = loader;
    }

    public int Id { get; set; }

    public LazyBlog LazyBlog
    {
        get => _loader.Load(this, ref _lazyBlog);
        set => _lazyBlog = value;
    }
}
```

This example is the same as the last example, except EF is matching the delegate type and parameter name and injecting a delegate for the ILazyLoader.Load method so that the entity class does not need to reference the EF assembly. A small extension method can be included in the entity assembly to make it a bit easier to use the delegate.

```C#
public class LazyPocoBlog
{
    private readonly Action<object, string> _loader;
    private ICollection<LazyPocoPost> _lazyPocoPosts = new List<LazyPocoPost>();

    public LazyPocoBlog()
    {
    }

    private LazyPocoBlog(Action<object, string> lazyLoader)
    {
        _loader = lazyLoader;
    }

    public int Id { get; set; }

    public ICollection<LazyPocoPost> LazyPocoPosts
        => _loader.Load(this, ref _lazyPocoPosts);
}

public class LazyPocoPost
{
    private readonly Action<object, string> _loader;
    private LazyPocoBlog _lazyPocoBlog;

    public LazyPocoPost()
    {
    }

    private LazyPocoPost(Action<object, string> lazyLoader)
    {
        _loader = lazyLoader;
    }

    public int Id { get; set; }

    public LazyPocoBlog LazyPocoBlog
    {
        get => _loader.Load(this, ref _lazyPocoBlog);
        set => _lazyPocoBlog = value;
    }
}

public static class TestPocoLoadingExtensions
{
    public static TRelated Load<TRelated>(
        this Action<object, string> loader,
        object entity,
        ref TRelated navigationField,
        [CallerMemberName] string navigationName = null)
        where TRelated : class
    {
        loader?.Invoke(entity, navigationName);

        return navigationField;
    }
}
```
ajcvickers added a commit that referenced this issue Jan 3, 2018
Parts of issues #3342, #240, #10509, #3797

The main things here are:
- Support for injecting values into parameterized entity constructors
  - Property values are injected if the parameter type and name matches
  - The current DbContext as DbContext or a derived DbContext type
  - A service from the internal or external service provider
  - A delegate to a method of a service
  - The IEntityType for the entity
- Use of the above to inject lazy loading capabilities into entities

For lazy loading, either the ILazyLoader service can be injected directly, or a delegate can be injected if the entity class cannot take a dependency on the EF assembly--see the examples below.

Currently all constructor injection is done by convention.

Remaining work includes:
- API/attributes to configure the constructor binding
- Allow factory to be used instead of using the constructor directly. (Functional already, but no API or convention to configure it.)
- Allow property injection for services
- Configuration of which entities/properties should be lazy loaded and which should not

### Examples

In this example EF will use the private constructor passing in values from the database when creating entity instances. (Note that it is assumed that _blogId has been configured as the key.)

```C#
public class Blog
{
    private int _blogId;

    // This constructor used by EF Core
    private Blog(
        int blogId,
        string title,
        int? monthlyRevenue)
    {
        _blogId = blogId;
        Title = title;
        MonthlyRevenue = monthlyRevenue;
    }

    public Blog(
        string title,
        int? monthlyRevenue = null)
        : this(0, title, monthlyRevenue)
    {
    }

    public string Title { get; }
    public int? MonthlyRevenue { get; set; }
}
```

In this example, EF will inject the ILazyLoader instance, which is then used to enable lazy-loading on navigation properties. Note that the navigation properties must have backing fields and all access by EF will go through the backing fields to prevent EF triggering lazy loading itself.

```C#
public class LazyBlog
{
    private readonly ILazyLoader _loader;
    private ICollection<LazyPost> _lazyPosts = new List<LazyPost>();

    public LazyBlog()
    {
    }

    private LazyBlog(ILazyLoader loader)
    {
        _loader = loader;
    }

    public int Id { get; set; }

    public ICollection<LazyPost> LazyPosts
        => _loader.Load(this, ref _lazyPosts);
}

public class LazyPost
{
    private readonly ILazyLoader _loader;
    private LazyBlog _lazyBlog;

    public LazyPost()
    {
    }

    private LazyPost(ILazyLoader loader)
    {
        _loader = loader;
    }

    public int Id { get; set; }

    public LazyBlog LazyBlog
    {
        get => _loader.Load(this, ref _lazyBlog);
        set => _lazyBlog = value;
    }
}
```

This example is the same as the last example, except EF is matching the delegate type and parameter name and injecting a delegate for the ILazyLoader.Load method so that the entity class does not need to reference the EF assembly. A small extension method can be included in the entity assembly to make it a bit easier to use the delegate.

```C#
public class LazyPocoBlog
{
    private readonly Action<object, string> _loader;
    private ICollection<LazyPocoPost> _lazyPocoPosts = new List<LazyPocoPost>();

    public LazyPocoBlog()
    {
    }

    private LazyPocoBlog(Action<object, string> lazyLoader)
    {
        _loader = lazyLoader;
    }

    public int Id { get; set; }

    public ICollection<LazyPocoPost> LazyPocoPosts
        => _loader.Load(this, ref _lazyPocoPosts);
}

public class LazyPocoPost
{
    private readonly Action<object, string> _loader;
    private LazyPocoBlog _lazyPocoBlog;

    public LazyPocoPost()
    {
    }

    private LazyPocoPost(Action<object, string> lazyLoader)
    {
        _loader = lazyLoader;
    }

    public int Id { get; set; }

    public LazyPocoBlog LazyPocoBlog
    {
        get => _loader.Load(this, ref _lazyPocoBlog);
        set => _lazyPocoBlog = value;
    }
}

public static class TestPocoLoadingExtensions
{
    public static TRelated Load<TRelated>(
        this Action<object, string> loader,
        object entity,
        ref TRelated navigationField,
        [CallerMemberName] string navigationName = null)
        where TRelated : class
    {
        loader?.Invoke(entity, navigationName);

        return navigationField;
    }
}
```
@max-arshinov
Copy link

Hi guys. What is the status of this issue? It looks that according to the roadmap (https://docs.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.0/features) it will not be implemented in EF Core 3.0. Will it?

@bricelam
Copy link
Contributor

Some support for constructor injection was added in 2.1.

@smitpatel
Copy link
Contributor

@ajcvickers - What is pending in this issue? Should we track it differently?

@ajcvickers
Copy link
Member

@bricelam @smitpatel This is actually about being able to inject services registered in the application D.I. container. We haven't implemented this yet.

@AndriySvyryd
Copy link
Member

Related to #13540

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

8 participants