在参考方法中注入要调用的方法

时间:2014-12-03 12:41:12

标签: c# asp.net-mvc entity-framework logging

让我们想象下面的情况(假设只有模型和视图/业务层,我会简化)

我正在使用Entity Framework,我希望将所有更改记录为Log表中的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将要实例化此LogContext即将调用我的Logger

如果我有2个项目,一个用于Model,另一个用于我的View / Business,我希望能够在Logger类中获取Logged用户,即使Model层不知道哪种View / Business正在调用它(MVC项目,Windows窗体等)。

我的想法是发送一个Func<>作为参数,此函数将使用户在View / Business层上(即使在模型上调用时),但这意味着重写所有SaveChanges调用以发送此函数。

我想知道是否有某种方式来注射"这个函数无需在整个项目中重写所有的SaveChanges。

非常感谢。

1 个答案:

答案 0 :(得分:1)

不是将用户返回到基本记录器,而是将其暴露给它不应该真正了解的概念,为什么不实现标记或附加信息系统?扩展现有的LogContext:

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,当记录器记录时,它会找到上下文存在的任何调用的上下文。