DbContext 中的 Explicit interface implementation

时间:2023-03-09 06:47:20
DbContext 中的 Explicit interface implementation

疑惑

前段时间一直再用Entity Framework 6,写了一些公用的方法,在这个过程中发现了DbContext实现的接口IObjectContextAdapter,可以通过这个接口访问到更底层的ObjectContext对象,比如

((IObjectContextAdapter)ctx).ObjectContext

当时就觉得很奇怪,为什么不能直接获取,而需要一次转换,主要是奇怪C#是通过什么形式把ObjectContext给hide住的,不过当时也没多想,忙于完成工作。最近比较系统的再过C#知识点的时候,发现了Explicit Interface implementation, 回想起了这个之前的那个疑惑,又去看了一下才发现,原来就是基于这个原理,其实是一个C#特别常见的功能,当你在实现某些接口的时候,IDE就已经告诉你了是隐示实现接口(implicit implementation)还是显示实现接口(explicit implementation)。

关于 Explicit interface implementation

简单的一句话就是,如果你想用接口当中的成员,必须使用接口本身的一种实现方式,使用这种方式可以为一些特定的情况而隐藏特定的实现,比如说要实现两个接口InterfaceA,InterfaceB,这两个接口中有相同的成员方法,实现类里边就可以共存了。

public interface InterfaceA
{
void Test();
} public interface InterfaceB
{
void Test();
} public class RunTest : InterfaceA, InterfaceB
{ void InterfaceB.Test()
{
throw new NotImplementedException();
} void InterfaceA.Test()
{
throw new NotImplementedException();
}
}

以这种方式实现后,实现类的实例是不能直接方法成员方法的。

DbContext 实现 IObjectContextAdapter

通过ILSpy反编译EntityFramwork.dll,并且查找DbContext后,就能看到实现IObjectContextAdapter的情况

/// <summary>
/// Returns the Entity Framework ObjectContext that is underlying this context.
/// </summary>
/// <exception cref="T:System.InvalidOperationException">Thrown if the context has been disposed.</exception>
[SuppressMessage("Microsoft.Design", "CA1033:InterfaceMethodsShouldBeCallableByChildTypes")]
ObjectContext IObjectContextAdapter.ObjectContext
{
get
{
this.InternalContext.ForceOSpaceLoadingForKnownEntityTypes();
return this.InternalContext.ObjectContext;
}
}

是以explicit implementation的方式实现的接口,并且不直接暴露给外部,所以这也就是为什么Entity Framework 6更希望你用DbContext这种封装了N层的类,而不希望你在通常的情况下用更底层的类,但如果要用只能通过IObjectContextAdapter本身来调用这个成员。