在引用的方法中注入要调用的方法

本文关键字:方法 调用 注入 引用 | 更新日期: 2023-09-27 18:33:07

让我们想象一下以下情况(我将通过假装只有模型和视图/业务层来简化(

我正在使用实体框架,我想将所有更改记录到 JSON 表中。

我已经能够通过覆盖 DbContext.SaveChanges(( 方法并读取 ChangeTracker(( 来实现这一点。

下面是一个示例:

public class LogContext : DbContext
{
    public LogContext(string context)
        : base(context)
    {
    }
    public override int SaveChanges()
    {
        ChangeTracker.DetectChanges();
        var added = ChangeTracker.Entries().Where(x => x.State == EntityState.Added).ToList();
        var modified = ChangeTracker.Entries().Where(x => x.State == EntityState.Modified).ToList();
        var deleted = ChangeTracker.Entries().Where(x => x.State == EntityState.Deleted).ToList();
        Logger.RecordAdded(added);
        Logger.RecordModified(modified);
        Logger.RecordDeleted(deleted);
    }
}

我的RealContext将实例化这个将调用我的LoggerLogContext

如果我有 2 个项目,一个用于模型,另一个用于我的视图/业务,例如,我希望能够在我的 Logger 类中获取登录用户,即使模型层不知道哪种视图/业务正在调用它(MVC 项目、Windows 窗体等(。

我的想法是发送一个 Func<> 作为参数,这个函数会让用户进入视图/业务层(即使在模型上被调用(,但这意味着重写所有 SaveChanges 调用来发送这个函数。

我想知道是否有某种方法可以"注入"这个函数,而无需在整个项目中重写我所有的 SaveChanges。

多谢。

在引用的方法中注入要调用的方法

与其将用户返回到基本记录器,这会将其暴露给它不应该真正了解的概念,为什么不实现标记或其他信息系统? 要扩展现有的日志上下文,请执行以下操作:

public class LogContext : DbContext
{
    private readonly Func<string> _getAdditionalInfoFunc;
    public LogContext(string context, Func<string> getAdditionalInfoFunc)
        : base(context)
    {
            _getAdditionalInfoFunc = getAdditionalInfoFunc;
    }
    public override int SaveChanges()
    {
        ChangeTracker.DetectChanges();
        var added = ChangeTracker.Entries()
                    .Where(x => x.State == EntityState.Added).ToList();
        var modified = ChangeTracker.Entries()
                    .Where(x => x.State == EntityState.Modified).ToList();
        var deleted = ChangeTracker.Entries()
                    .Where(x => x.State == EntityState.Deleted).ToList();
        string extraInfo = _getAdditionalInfoFunc != null
                         ? _getAdditionalInfoFunc()
                         : string.Empty;
        Logger.RecordAdded(added, extraInfo);
        Logger.RecordModified(modified, extraInfo);
        Logger.RecordDeleted(deleted, extraInfo);
    }
} 

这将是一个非常灵活的解决方案。 然后,您可以让注入器注入一个 func,该函数以自由格式返回一个字符串,其中包含您需要的尽可能多的上下文相关信息。

与根据需要它的类的位置注入不同的实现相比,这样做的好处是,有时可能会在用户操作的上下文中调用低级代码。 如果将特定记录器提供给特定类,则可能会丢失该相关上下文信息。 相反,如果您有一个始终检查用户上下文的 func,则当记录器记录时,它将查找存在上下文的任何调用的上下文。