Skip to content

Commit

Permalink
Don't resolve collections for not registered types when IServiceProvi…
Browse files Browse the repository at this point in the history
…derIsService is used, in this case the model binder of aps.net core should create the object. Closes GH-391
  • Loading branch information
jeremydmiller authored and rizi committed Nov 23, 2023
1 parent adc00b8 commit 4c11f3c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,27 @@ public void fix_for_368_auto_resolve_enumerable_concretes_and_generics()
container.IsService(typeof(IGenericService1<ConcreteClass>)).ShouldBeTrue();
}

[Fact]
public void fix_for_391_dont_resolve_collections_with_not_registered_type()
{
var containerWithNoRegistrations = Container.Empty();

containerWithNoRegistrations.IsService(typeof(IEnumerable<ConcreteClass>)).ShouldBeFalse();
containerWithNoRegistrations.IsService(typeof(IReadOnlyCollection<ConcreteClass>)).ShouldBeFalse();
containerWithNoRegistrations.IsService(typeof(IList<ConcreteClass>)).ShouldBeFalse();
containerWithNoRegistrations.IsService(typeof(List<ConcreteClass>)).ShouldBeFalse();

var containerWithRegistrations = Container.For(services =>
{
services.ForConcreteType<ConcreteClass>();
});

containerWithRegistrations.IsService(typeof(IEnumerable<ConcreteClass>)).ShouldBeTrue();
containerWithRegistrations.IsService(typeof(IReadOnlyCollection<ConcreteClass>)).ShouldBeTrue();
containerWithRegistrations.IsService(typeof(IList<ConcreteClass>)).ShouldBeTrue();
containerWithRegistrations.IsService(typeof(List<ConcreteClass>)).ShouldBeTrue();
}

public interface IService
{
}
Expand Down
17 changes: 16 additions & 1 deletion src/Lamar/ServiceGraph.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
Expand Down Expand Up @@ -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();
Expand Down

0 comments on commit 4c11f3c

Please sign in to comment.