Hello, I'm trying to inject a custom implementation of IDbContextOptionsExtension using the WithExtension method on the IDbContextOptionsBuilder and I'm failing miserably. Now I've looked for some sort of documentation but couldn't find none.
Basically I use the .AddDbContext and inside the config delegate I call .UseSqlServer and .Options.WithExtension(new CustomExtension()), problem is that in the constructor of the DbContext the DbContextOptions doesn't have that extension that I added. Am I doing something wrong or is this a bug?
Thank you,
Emanuel
@emanuelmd Options extensions are intended primarily for use by database provider code--what is it that you want to write an extension for and how are you intending to consume it? Have you considered using normal constructor injection for application options into the DbContext--this is usually much easier.
That being said, if you're going to implement an options extension, then follow the pattern of one of the ones that already exist--such as InMemoryOptionsExtension. Make sure to implement the Clone and WithXxx methods--the extensions are immutable objects.
Well the problem isn't the implementation, I'm trying to inject a custom schema name into the DbContext, I managed to register my extension. Problem is that it doesn't show up in the constructor of given DbContext, calling DbContextOptions
@ajcvickers Thank you for that suggestion. It works great for my own case, when I just want to extend the db context's model
On implementing that the suggestion does not work for pooling
@Tarig0 With pooling it is very easy to shoot yourself in the foot by trying to do this because the service injected may be stale due to the context instance being re-used.
Curious: have you tested the perf using pooling? How much perf benefit is it providing to your app?
I have not. I'm doing a lot of development and pooling came up as an option so I swapped out the function to take advantage of it.
What would be a good way of testing the pooling benefit? Most perf tools, that I used, don't like core
Just had a thought, could you scan the DI container, to see if what will be injected is singletons?
@Tarig0 In general analyzing D.I. dependencies is something we don't want to do because we end up attempting to replicate the behavior of the D.I. container, which is both complex and fragile. In this case, it would likely be possible because only the directly injected dependencies need to be scanned, since if any of these in turn depend on scoped services, then that's already an application bug. However, I don't think we will end up doing this, at lease right now, because context pooling is something that helps when everything else in the request is doing very little work and there is high throughput creating memory pressure--that's what starts to make context instance creation a significant part of the perf profile. Once a context is making use of other services, it seems less likely that this will be the case. So I think we would likely have to either see or create perf numbers that show the benefit here, otherwise the answer is to just not use pooling.
I think my case would be better served with having derived DBContexts.
Since what I have is
Base
|- ModuleA
|- ModuleB
Where the Modules have a class with an OnModelCreating function that the BaseDBContext Calls, this is what is injected into the BaseDBContext. This was so that I could have one place for migrations.
Most helpful comment
Well the problem isn't the implementation, I'm trying to inject a custom schema name into the DbContext, I managed to register my extension. Problem is that it doesn't show up in the constructor of given DbContext, calling DbContextOptions.FindExtension() returns null and debugging I only see the two internal ones added by default.