I am using a third party library GraphDiff which adds Extension methods to DBContext class. My Context class is inherited from Interface like following
MyContext: DbContext,IMyContext
IoC contained register MyContext as IMyContext. Interface doesn't have extension method's signature and third. Now i am not getting how MyContext will have that extension method? If i create Object of MyContext it has that method but when it gets Inject it doesn't
Extensions methods are not part of the type, it is a C# syntactic sugar. When you do :
myContext.ExtensionMethod();
the compiler will generate the following code :
ExtensionContainer.ExtensionMethod(myContext);
Where ExtensionContainer
is defined like this :
public static class ExtensionContainer
{
public static void ExtensionMethod(this DbContext context)
{ }
}
When you use an extension method, the compiler will call a static method. See Extension Methods (C# Programming Guide) for more information.
You can't use the extension method in your case because context
is no longer a DbContext
but IMyContext
and the extension methods are defined for DbContext
not for IMyContext
.
If you want to use these extension methods, one possible solution is to add them to your interface.
public interface IMyContext
{
T UpdateGraph<T>(T entity, Expression<Func<IUpdateConfiguration<T>, object>> mapping, UpdateParams updateParams = null) where T : class
// other methods / properties
}
And in your concrete context you will be allowed to use the extension method
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);
}
}
Another solution is not to rely anymore on IMyContext
but injecting MyContext
. This solution will make your application more difficult to test and will introduce a strong dependency with Entity Framework.
By the way doing so may break Single Responsibility Principle but I don't see an easy way to solve this without big refactoring.