将依赖注入到实体类中

8
使用Asp.Net Core,我们可以在控制器/存储库中使用依赖注入。
然而,我希望在我的实体类中进行一些日志记录。
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;
    }
}

当EntityFramework实例化Person类时,它不会尝试注入任何依赖项。
我能强制执行吗?我是不是完全走错了方向?
最终,我只想能够在整个应用程序中一致地使用日志记录。
谢谢,

6
为什么要在领域类中使用日志记录?只需在使用您的领域类的类(控制器/存储库)中使用日志记录即可。 - user743414
1
在这种情况下,HasCat() 在实例上执行一些比在控制器中更有意义的操作。我可以简单地在调用 HasCat() 的位置记录日志,但我更愿意在方法内部完成它,这样我就不会重复并且我也不会“忘记”。 - JNB
1
我能强制这样做吗?可能可以,但你不应该这样做。我是不是完全走错了路?是的。通过混合关注点,您正在做出糟糕的设计选择。实体不应具有实现方面的问题。如果它们这样做,它们就不再是实体了。日志记录是一个横切关注点。 - Nkosi
1
相关链接:https://dev59.com/4m445IYBdhLWcg3we6V9 - Steven
1
相关链接:https://dev59.com/8mkw5IYBdhLWcg3wbqGZ#9915056 - Steven
显示剩余3条评论
1个回答

6

虽然可以这样做,但我不建议这样做,因为我同意评论者的观点,即日志记录应该放在您的服务和控制器中。

EF Core 2.1允许将DbContext注入到私有构造函数中,EF将调用它。请参阅官方文档

首先,您需要在DbContext类中公开一个LoggerFactory属性。

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

    public ILoggerFactory LoggerFactory { get; }
}

然后,您可以将DbContext注入到实体类的私有构造函数中。
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;
    }
}

我真的希望EF Core 2.1可以将任何东西注入到构造函数中,从您的服务容器中获取(不仅仅是那些在DbContext中手动提供的)。 - Jeremy Armstrong
4
这并不是一个好的答复,因为它明显建议使用贫血的领域模型,且没有进一步的解释。 - Iso J
2
@IsoJ 我在第一行就明确表示“我不建议这样做”,这难道不够清楚吗? - Brad
11
@Brad,你明显建议仅将日志记录放在服务和控制器中,这基本意味着实体类中没有业务逻辑。这几乎是贫血领域模型的定义。对于dotnet core应用程序中配置日志的方式,我想加上个人意见。我真的不喜欢通过构造函数注入日志记录器的方式。日志记录不是一种依赖关系。它是整个应用程序的横切关注点。例如,我更喜欢Java的做法。 - Iso J
1
如果一个类需要另一个类才能执行功能(如日志记录),那么它对该类具有依赖性。日志记录与注入某些用户数据转换器或其他服务、功能或依赖项没有任何区别。 - James
@James,这实际上是由dotnet开发人员做出的设计决策。我必须说我不喜欢这个决定。以Java为例,日志记录是一个独立于依赖注入范围之外的关注点。我不想在这里进行语言战争,但我没有看到注入记录器的任何好处。这只是额外的工作。您最终可以通过一些间谍开始单元测试记录,但我还没有遇到过那种需要。 - Iso J

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接