Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency Injection into Entity Class

Using Asp.Net Core we can make use of Dependency Injection in controllers/repositories.

However, I wish do do some logging in my Entity Class.

class Person
{
    private ILogger<Person> _logger;
    private List<Pets> pets;

    public Person(ILogger<Person> logger)
    {
        _logger = logger;
    }

    public bool HasCat()
    {
        _logger.LogTrace("Checking to see if person has a cat.");
        // logic to determine cat ownership
        hasCat = true;
        return hasCat;
    }
}

When the Person class is instantiated by EntityFramework it does not attempt to inject any dependencies.

Can I force this? Am i going about it in completely the wrong way?

Ultimatley I just want to be able to use logging consistently throughout the application.

Thanks,

like image 509
JNB Avatar asked Jun 28 '18 12:06

JNB


People also ask

Is dependency injection possible with abstract class?

Any concrete class inheriting the abstract class should be instantiable with a constructor (if not abstract itself of course). But use of constructor is prohibited by Spring because any class that we instantiate this way cannot be taken in charge by Spring's automated dependency injection.

Should I use transient or scoped?

Use Transient lifetime for the lightweight service with little or no state. Scoped services service is the better option when you want to maintain state within a request. Singletons are created only once and not destroyed until the end of the Application. Any memory leaks in these services will build up over time.

When should I use IServiceProvider?

The IServiceProvider is responsible for resolving instances of types at runtime, as required by the application. These instances can be injected into other services resolved from the same dependency injection container. The ServiceProvider ensures that resolved services live for the expected lifetime.


1 Answers

It is possible but I don't recommend it because I agree with commenters that logging belongs in your services and controllers.

EF Core 2.1 allows injecting the DbContext into a private constructor that EF will invoke. See the official docs.

First you need to expose a LoggerFactory property in your DbContext class.

public class MyDbContext : DbContext
{
    public MyDbContext(DbContextOptions<MyDbContext> options, ILoggerFactory loggerFactory = null)
    {
        LoggerFactory = loggerFactory;
    }

    public ILoggerFactory LoggerFactory { get; }
}

Then you can inject the DbContext into a private constructor in your entity class.

public class Person
{
    private readonly ILogger _logger;

    public Person() { } // normal public constructor

    private Person(MyDbContext db) // private constructor that EF will invoke
    {
        _logger = db.LoggerFactory?.CreateLogger<Person>();
    }

    public bool HasCat()
    {
        _logger?.LogTrace("Check has cat");
        return true;
    }
}
like image 51
Brad Avatar answered Oct 06 '22 01:10

Brad