-
Notifications
You must be signed in to change notification settings - Fork 317
Spec out implicit behaviors of the DI container and service collection #379
Comments
That would be nice! 👍 |
May be not a right place, but it is quite explicit and exemplary how DryIoc setups DI adapter:
|
@dadhi it's definitely the right place 😄 |
Moving to backlog. |
On the Autofac implementation we're definitely getting questions (as outlined in that SimpleInjector issue) about whether there's a guaranteed order of things coming back from enumerable/collection services. Here's the latest one. Is there a prescribed (or required) order for enumerables returned from the service provider? |
Out of curiosity, what parts of the ASP.NET Core framework explicitly depend on the DI container and registration system? I know that the MVC registers services. But does it need to? Does it still have factory classes for constructing controllers and views? It seems odd to me that to use a piece of middleware I need to remember to register it's services in a different location. Having a single DI container does seem to provide a way to implicitly make middleware "DI friendly", but this too could be solved by providing a middleware factory and allowing middleware to be constructed via that, again bypassing the conforming container. In fact, Autofac provided this kind of middleware factory for OWIN. |
@halter73 can you respond to some of these questions? |
AFAIK, |
Even with |
Yes - enumerables should be returned in the order added - so fwk services should appear before app servces in an enumerable because the fwk services are what is setting the default. So the expectation is correct. There was a set of base test cases in the DI repo that could be run against the built-in container, and could be used by third-party container adapters to validate correctness of the assumptions. Was the project with the abstract base test cases deleted at some point? It would have been the place where the assumptions were codified. |
The tests are still there but there is no test around the ordering of enumerables, which is where some of the challenge is arising. |
Actually, I have another issue with this: because the framework is registering services, how do I register services before it? Say I want to replace the per-request-scope generating filter. It is written to do nothing if a scope has already been set, but I can't register a filter before it, so it will always be the first middleware run. |
Regarding the small set of specifications brought up in simpleinjector/SimpleInjector#41 (comment). Most of these already have specification tests:
|
Off the top of the head, here are some other things that we do that we probably don’t test:
@davidfowl Do any of these warrant adding a specification test for? |
This refers to the fact that some DI containers cannot adapt the Even with all of these "Conforming container" specifications there is still a big impedance mismatch between your container's (and service registration system's) features and the features available on the DI container of MY choice. The more I look at this problem the more I wonder what exactly is being solved by having |
@PleasantD Given multiple registrations for a given service type in an I personally don't know whether asking containers to maintain ordering is a bridge too far, but I do know that ordering is a "feature" that we have come to rely on in several places in ASP.NET. Initially, we planned to fix our usage not to rely on ordering (and I wish we had/could), but there's a risk that we wouldn't catch everything prior to 1.0. As for exposing |
@smitpatel Said he could help investigate whether Autofac works as expected with EF. @ajcvickers told me EF should not rely on service ordering. Edit: added not |
replacing
works as expected in EF functional tests. |
While you're extending the Spec Tests, are you sure that the following code snippet from DependencyInjectionSpecificationTests.cs is correct? public static TheoryData ServiceContainerPicksConstructorWithLongestMatchesData
{
var fakeService = new FakeService();
var multipleService = new FakeService();
var factoryService = new TransientFactoryService();
var scopedService = new FakeService();
[...]
new ServiceCollection()
.AddSingleton<IFakeService>(fakeService)
.AddSingleton<IFakeMultipleService>(multipleService)
.AddSingleton<IFakeScopedService>(scopedService)
.AddSingleton<IFactoryService>(factoryService),
new TypeWithSupersetConstructors(multipleService, factoryService, fakeService, scopedService)
} according to the IFake* names the fourth parameter is a scopedService, but all 4 services are added as singletons. Either the name is wrong or the AddSingleton is wrong. According to the names I would have also expected other implementations. |
@Tornhoof seems like |
In my Kestrel issue ( I have replaced // var container = containerBuilder.Build();
var result = new disposingServiceProvider();
result.ServiceProvider = container.Resolve<IServiceProvider>();
result.Container = container;
return result; with private class disposingServiceProvider : IServiceProvider, IDisposable
{
public IServiceProvider ServiceProvider;
public IContainer Container;
public object GetService(Type serviceType)
{
return ServiceProvider.GetService(serviceType);
}
public void Dispose()
{
Container.Dispose();
}
} And this seems to fix my shutdown issues. |
Need to add a spec test for the service provider being disposable to capture that behavior. |
@davidfowl let's discuss this when you're around |
We are closing this issue because no further action is planned for this issue. If you still have any issues or questions, please log a new issue with any additional details that you have. |
Here's a good starting point:
simpleinjector/SimpleInjector#41 (comment)
We should capture all of these in our specification tests.
/cc @lodejard @Eilon @pranavkm
The text was updated successfully, but these errors were encountered: