【问题标题】:Resolving class that has extension methods with AutoFac使用 AutoFac 解析具有扩展方法的类
【发布时间】:2015-05-18 20:35:02
【问题描述】:

我正在使用第三方库 GraphDiff,它将扩展方法添加到 DBContext 类。我的 Context 类是从 Interface 继承的,如下所示

 MyContext: DbContext,IMyContext 

IoC 包含将 MyContext 注册为 IMyContext。接口没有扩展方法的签名和第三个。现在我不知道 MyContext 将如何拥有该扩展方法?如果我创建 MyContext 的对象,它具有该方法,但是当它被 Inject 时它没有

【问题讨论】:

  • 过去扩展方法是否有效?
  • 这是一个提供扩展方法的 Nuget 包。我的 Context 实现了接口,以便我可以在其上使用 Ioc。现在的问题是如何让我的界面感知

标签: entity-framework autofac graphdiff


【解决方案1】:

扩展方法不是类型的一部分,它是一个 C# syntactic sugar。当你这样做时:

myContext.ExtensionMethod(); 

编译器将生成以下代码:

ExtensionContainer.ExtensionMethod(myContext); 

ExtensionContainer 的定义如下:

public static class ExtensionContainer 
{
    public static void ExtensionMethod(this DbContext context)
    { }
}

当您使用扩展方法时,编译器将调用静态方法。有关更多信息,请参阅Extension Methods (C# Programming Guide)

您不能在您的情况下使用扩展方法,因为context 不再是DbContext,而是IMyContext,并且扩展方法是为DbContext 而不是为IMyContext 定义的。

如果您想使用这些扩展方法,一种可能的解决方案是将它们添加到您的界面中。

public interface IMyContext
{
    T UpdateGraph<T>(T entity, Expression<Func<IUpdateConfiguration<T>, object>> mapping, UpdateParams updateParams = null) where T : class 

    // other methods / properties
}

并且在您的具​​体上下文中,您将被允许使用扩展方法

public class MyContext : DbContext, IMyContext
{
    public T UpdateGraph<T>(T entity, Expression<Func<IUpdateConfiguration<T>, object>> mapping, UpdateParams updateParams = null) where T : class
    {
        DbContextExtensions.UpdateGraph<T>(this, entity, mapping, updateParams); 
    }
}

另一个解决方案是不再依赖IMyContext,而是注入MyContext。此解决方案将使您的应用程序更难测试,并将引入与 Entity Framework 的强依赖关系。

顺便说一句,这样做可能会破坏Single Responsibility Principle,但我没有看到一个简单的方法来解决这个问题而无需大的重构。

【讨论】:

  • 如果我注入 MyContext 并摆脱 IMyContext 会怎样?
  • 它会工作,但测试会更加困难,并且您的应用程序将与 Entity Framework 高度耦合
  • public static T UpdateGraph(this DbContext context, T entity, Expression, object>> mapping, UpdateParams updateParams = null) where T : class //这是我所追求的扩展方法的签名。如何将其添加到 IMyContext
  • 在 MyContext 中它抱怨 ,在签名中的类之后添加了一个 new() // T UpdateGraph(T entity, Expression, object>>映射,UpdateParams updateParams = null) where T : class, new()
  • 第三种低接触/快速(但 hacky)解决方案是只定义在 IMyContext 上定义的通过扩展方法,该方法试图在调用之前将 IMyContext 的实例转换为 DbContext真正的方法。您可能需要稍后进行重构,但如果您有截止日期,它会让您度过难关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-07-06
  • 1970-01-01
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多