Skip to content

Commit 97ccab8

Browse files
committed
fixed: #578
1 parent 49315e7 commit 97ccab8

File tree

3 files changed

+62
-13
lines changed

3 files changed

+62
-13
lines changed

src/DryIoc/Container.cs

+24-9
Original file line numberDiff line numberDiff line change
@@ -4442,20 +4442,34 @@ public static GeneratedExpressions GenerateResolutionExpressions(
44424442
/// <summary>Excluding open-generic registrations, cause you need to provide type arguments to actually create these types.</summary>
44434443
public static bool DefaultValidateCondition(ServiceRegistrationInfo reg) => !reg.ServiceType.IsOpenGeneric();
44444444

4445+
// todo: @vNext instead of `condition` we may use a transformer to close the open-generic types. But may be having `roots` parameters covers it as well.
44454446
/// <summary>Helps to find potential problems in service registration setup. Method tries to resolve the specified registrations, collects exceptions,
44464447
/// and returns them to user. Does not create any actual service objects. You must specify <paramref name="condition"/> to define your resolution roots,
44474448
/// otherwise container will try to resolve all registrations, which usually is not realistic case to validate.</summary>
44484449
public static KeyValuePair<ServiceInfo, ContainerException>[] Validate(this IContainer container, Func<ServiceRegistrationInfo, bool> condition = null)
44494450
{
4450-
var noOpenGenericsWithCondition = condition == null
4451-
? (Func<ServiceRegistrationInfo, bool>)DefaultValidateCondition
4452-
: (r => condition(r) && DefaultValidateCondition(r));
4453-
4454-
var roots = container.GetServiceRegistrations().Where(noOpenGenericsWithCondition).Select(r => r.ToServiceInfo()).ToArray();
4455-
if (roots.Length == 0)
4456-
Throw.It(Error.FoundNoRootsToValidate, container);
4451+
var roots = ArrayTools.Empty<ServiceRegistrationInfo>();
4452+
if (condition == null)
4453+
{
4454+
var allNonGenericRegistrations = container.GetServiceRegistrations().Where(DefaultValidateCondition).ToArray();
4455+
if (allNonGenericRegistrations.Length == 0)
4456+
Throw.It(Error.FoundNoRootsToValidate, container);
4457+
4458+
// We try to find the registrations marked by `Setup.With(asResolutionRoot: true)` and if nothing found, fallback to the all found.
4459+
// This allow to make asResolutionRoot marking to be optional for validate, but if used - provide the convinient validation by convention.
4460+
roots = allNonGenericRegistrations.Match(r => r.Factory.Setup.AsResolutionRoot);
4461+
if (roots.Length == 0)
4462+
roots = allNonGenericRegistrations;
4463+
}
4464+
else
4465+
{
4466+
// condition overrides whatever resolution roots are marked in registrations
4467+
roots = container.GetServiceRegistrations().Where(r => condition(r) && DefaultValidateCondition(r)).ToArray();
4468+
if (roots.Length == 0)
4469+
Throw.It(Error.FoundNoRootsToValidate, container);
4470+
}
44574471

4458-
return container.Validate(roots);
4472+
return container.Validate(roots.Map(r => r.ToServiceInfo()));
44594473
}
44604474

44614475
/// <summary>Same as the Validate with the same parameters but throws the exception with all collected errors</summary>
@@ -14529,7 +14543,8 @@ public static readonly int
1452914543
"The `serviceTypes` passed to Validate method is null or empty. Please pass the type(s) you want to Validate."),
1453014544
ValidateFoundErrors = Of(
1453114545
"Validate method found the errors, please check the ContainerException.CollectedExceptions for the details." + NewLine +
14532-
"If you see too many (unexpected) errors, try narrowing the resolution roots by passing the selected service types or the condition to the Validate(AndThrow) method."),
14546+
"If you see too many (unexpected) errors, try narrowing the resolution roots by passing the selected service types or the condition to the Validate(AndThrow) method." + NewLine +
14547+
"Or alternatively, mark the service registrations with `setup: Setup.With(asResolutionRoot: true)`."),
1453314548
UnableToInterpretTheNestedLambda = Of(
1453414549
"Unable to interpret the nested lambda with Body:" + NewLine + "{0}"),
1453514550
WaitForScopedServiceIsCreatedTimeoutExpired = Of(

test/DryIoc.IssuesTests/GHIssue576_Extension_methods_not_being_handled_correctly_in_MadeOf_service_returning_expression.cs

+36-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@ public int Run()
1515
Test_factory_extension_method_GHIssue577();
1616
Test_factory_extension_method_GHIssue577_exclude_from_Validate_via_metadata();
1717

18-
return 4;
18+
Test_factory_extension_method_GHIssue578_respect_Setup_AsResolutionRoot();
19+
20+
return 5;
1921
}
2022

2123
[Test]
@@ -136,6 +138,39 @@ public void Test_factory_extension_method_GHIssue577_exclude_from_Validate_via_m
136138
Assert.AreEqual(typeof(Foo).FullName, ((SerilogLogger)foo.Logger).TypeName);
137139
}
138140

141+
[Test]
142+
public void Test_factory_extension_method_GHIssue578_respect_Setup_AsResolutionRoot()
143+
{
144+
var container = new Container();
145+
146+
var loggerFactory = new SerilogLoggerFactory();
147+
148+
container.RegisterInstance<ILoggerFactory>(loggerFactory);
149+
150+
container.Register(
151+
Made.Of(_ => ServiceInfo.Of<ILoggerFactory>(),
152+
f => f.CreateLogger(null)),
153+
setup: Setup.With(condition: r => r.Parent.ImplementationType == null, asResolutionRoot: true));
154+
155+
container.Register(
156+
Made.Of(_ => ServiceInfo.Of<ILoggerFactory>(),
157+
f => f.CreateLogger(Arg.Index<Type>(0)),
158+
r => r.Parent.ImplementationType),
159+
setup: Setup.With(condition: r => r.Parent.ImplementationType != null));
160+
161+
container.Register<Foo>();
162+
163+
var errors = container.Validate();
164+
165+
Assert.IsEmpty(errors);
166+
167+
var log = container.Resolve<ILogger>();
168+
Assert.IsNull(((SerilogLogger)log).TypeName);
169+
170+
var foo = container.Resolve<Foo>();
171+
Assert.AreEqual(typeof(Foo).FullName, ((SerilogLogger)foo.Logger).TypeName);
172+
}
173+
139174
public sealed class Foo
140175
{
141176
public readonly ILogger Logger;

test/DryIoc.TestRunner/Program.cs

+2-3
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,9 @@ public class Program
88
{
99
public static void Main()
1010
{
11-
// RunAllTests();
12-
13-
new GHIssue576_Extension_methods_not_being_handled_correctly_in_MadeOf_service_returning_expression().Run();
11+
RunAllTests();
1412

13+
// new GHIssue576_Extension_methods_not_being_handled_correctly_in_MadeOf_service_returning_expression().Run();
1514
// new GHIssue116_ReOpened_DryIoc_Resolve_with_decorators_goes_wrong_for_parallel_execution().Run();
1615
// new RequiredPropertiesTests().Run();
1716
// new PropertyResolutionTests().Run();

0 commit comments

Comments
 (0)