diff --git a/src/Lamar.Testing/IoC/Acceptance/IServiceProviderIsService_implementation.cs b/src/Lamar.Testing/IoC/Acceptance/IServiceProviderIsService_implementation.cs index fd01f986..ae7559b5 100644 --- a/src/Lamar.Testing/IoC/Acceptance/IServiceProviderIsService_implementation.cs +++ b/src/Lamar.Testing/IoC/Acceptance/IServiceProviderIsService_implementation.cs @@ -37,6 +37,27 @@ public void fix_for_368_auto_resolve_enumerable_concretes_and_generics() container.IsService(typeof(IGenericService1)).ShouldBeTrue(); } + [Fact] + public void fix_for_391_dont_resolve_collections_with_not_registered_type() + { + var containerWithNoRegistrations = Container.Empty(); + + containerWithNoRegistrations.IsService(typeof(IEnumerable)).ShouldBeFalse(); + containerWithNoRegistrations.IsService(typeof(IReadOnlyCollection)).ShouldBeFalse(); + containerWithNoRegistrations.IsService(typeof(IList)).ShouldBeFalse(); + containerWithNoRegistrations.IsService(typeof(List)).ShouldBeFalse(); + + var containerWithRegistrations = Container.For(services => + { + services.ForConcreteType(); + }); + + containerWithRegistrations.IsService(typeof(IEnumerable)).ShouldBeTrue(); + containerWithRegistrations.IsService(typeof(IReadOnlyCollection)).ShouldBeTrue(); + containerWithRegistrations.IsService(typeof(IList)).ShouldBeTrue(); + containerWithRegistrations.IsService(typeof(List)).ShouldBeTrue(); + } + public interface IService { } diff --git a/src/Lamar/ServiceGraph.cs b/src/Lamar/ServiceGraph.cs index 7f14dd7a..0c4e7de6 100644 --- a/src/Lamar/ServiceGraph.cs +++ b/src/Lamar/ServiceGraph.cs @@ -1,4 +1,5 @@ using System; +using System.Collections; using System.Collections.Generic; using System.Linq; using System.Reflection; @@ -483,14 +484,28 @@ internal ServiceFamily TryToCreateMissingFamilyWithNetCoreRules(Type serviceType return new ServiceFamily(serviceType, DecoratorPolicies); } + Type serviceTypeToLookFor = getServiceTypeThatTakesCollectionsIntoAccount(serviceType); + var found = FamilyPolicies.Where(x => x is not ConcreteFamilyPolicy) - .FirstValue(x => x.Build(serviceType, this)); + .FirstValue(x => x.Build(serviceTypeToLookFor, this)); _lookingFor.Remove(serviceType); return found; } + private Type getServiceTypeThatTakesCollectionsIntoAccount(Type serviceType) + { + if (!typeof(IEnumerable).IsAssignableFrom(serviceType) || serviceType.GetGenericArguments().Length != 1) + return serviceType; + + Type type = serviceType.GetGenericArguments().Single(); + + bool isTypeRegistered = _services.Any(descriptor => descriptor.ServiceType == type); + + return isTypeRegistered ? serviceType : type; + } + internal void ClearPlanning() { _chain.Clear();