A year and a half ago we posted an article on how we were able to plug into EF Core pipeline and inject our own IMethodCallTranslator
. That let us leverage SQL-native encryption functionality with EF Core 3.1 and was ultimately a win. A lot has changed in the ecosystem, we’ve got .NET 5 and and .NET 6 coming up soon. So, we could not help but wonder…
Will it work with EF Core 6?
Apparently, EF6 is mostly an evolutionary step over EF5. That said, we totally missed previous version. So it is unclear to what extent the EF team has reworked their internal APIs. Most of the extensibility points we used were internal and clearly marked as “not for public consumption”. With that in mind, our concerns seemed valid.
Turns out, the code needs change…
The first issue we needed to rectify was implementing ShouldUseSameServiceProvider
: from what I can tell, it’s needed to cache services more efficiently, but in our case setting it to default value seems to make sense.
But that’s where things really went sideways:
Apparently adding our custom IDbContextOptionsExtension
resets the cache and by the time EF arrives at Model initialisation, instance of DI container gets wiped, leaving us with a bunch of null references (including the one above).
One line fix
I am still unsure why EF so upset when we add new extension. Stepping through the code would likely provide me with the answer but I feel it’s not worth the effort. Playing around with service scopes I however noticed that many built-in services get registered using different extension method with Scoped lifecycle. This prompted me to try change my registration method signature and voila:
And as usual, fully functioning code sits on GitHub.