Well ... I solved the problem, but I do not understand why it mattered.
It comes down to some subtle differences from what I originally posted, what I forgot, because I thought the details were inconsequential and would be distracted from the question. In fact, my container was not defined locally; rather, it was a protected property of my middleware (it is inherited for integration testing purposes):
protected IContainer Container { get; private set; }
Then the initialization call was called inside the Invoke() method:
Container = context.GetNestedContainer();
Using the logging instructions in the whole method, I moved on to the following code (as mentioned in the issue with adding a log):
_logger.Debug($"Line 1 Context={context.GetHashCode}, Container={Container.GetHashCode()}"); var db = MyDbContext.ForShard(shardKey.Value); // no need for "using", since DI will automatically dispose _logger.Debug($"Line 2 Context={context.GetHashCode}, Container={Container.GetHashCode()}"); Container.Configure(cfg => cfg.For<MyDbContext>().Use(db)); await Next.Invoke(context);
And amazingly, this is what came out of the magazines:
Line 1 Context = 56852305, Container = 48376271
Line 1 Context = 88275661, Container = 85736099
Line 2 Context = 56852305, Container = 85736099
Line 2 Context = 88275661, Container = 85736099
Awesome! My middleware's Container property got a magical replacement! This is despite the fact that it is defined using a private set , and in any case, to be safe, I checked the code MyDbContext.ForShard() and did not find anything that could ruin the link for Container .
So what was the solution? I declared a local variable Container immediately after initialization and used it instead.
Now it works, but I donβt understand why and how it might matter.
The bounty goes to a person who can explain this.