Skip to content

Commit ddf5295

Browse files
add ResolveStrategy to make it config options more clear
While writing documentation I realized the parameter names could be confusing. It wasn't obvious from the names that a default behavior was being overridden. This will make it easier to introduce other strategies, like ResolveOrThrow or Skip.
1 parent c3ee5b8 commit ddf5295

File tree

9 files changed

+94
-125
lines changed

9 files changed

+94
-125
lines changed
Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
using System;
22
using Autofac;
3-
using CommandDotNet.Builders;
43
using CommandDotNet.Execution;
54

65
namespace CommandDotNet.IoC.Autofac
@@ -11,17 +10,11 @@ public static class AppRunnerConfigurationExtensions
1110
/// <param name="appRunner">the <see cref="AppRunner"/></param>
1211
/// <param name="container">the Autofac container to use</param>
1312
/// <param name="runInScope">if provided, the scope will be created at the beginning of the run and disposed at the end</param>
14-
/// <param name="useResolveForArgumentModel">
15-
/// <see cref="IDependencyResolver.TryResolve"/> is the default to resolve <see cref="IArgumentModel"/>s.
16-
/// Set this to true to use <see cref="IDependencyResolver.Resolve"/>.
17-
/// If Resolve is used and returns null, this framework will attempt to
18-
/// instantiate an instance.
13+
/// <param name="argumentModelResolveStrategy">
14+
/// the <see cref="ResolveStrategy"/> used to resolve <see cref="IArgumentModel"/>s.
1915
/// </param>
20-
/// <param name="useTryResolveForCommandClass">
21-
/// <see cref="IDependencyResolver.Resolve"/> is the default to resolve command classes.
22-
/// Set this to true to use <see cref="IDependencyResolver.TryResolve"/>.
23-
/// If Resolve is used and returns null, this framework will attempt to
24-
/// instantiate an instance.
16+
/// <param name="commandClassResolveStrategy">
17+
/// the <see cref="ResolveStrategy"/> used to resolve command classes.
2518
/// </param>
2619
/// <param name="useLegacyInjectDependenciesAttribute">
2720
/// when true, resolve instances for properties marked with [InjectProperty].
@@ -31,28 +24,15 @@ public static AppRunner UseAutofac(
3124
this AppRunner appRunner,
3225
IContainer container,
3326
Func<CommandContext, IDisposable> runInScope = null,
34-
bool useResolveForArgumentModel = false,
35-
bool useTryResolveForCommandClass = false,
27+
ResolveStrategy argumentModelResolveStrategy = ResolveStrategy.TryResolve,
28+
ResolveStrategy commandClassResolveStrategy = ResolveStrategy.Resolve,
3629
bool useLegacyInjectDependenciesAttribute = false)
3730
{
38-
return appRunner
39-
.UseDependencyResolver(new AutofacResolver(container),
40-
useResolveForArgumentModel: useResolveForArgumentModel,
41-
useTryResolveForCommandClass: useTryResolveForCommandClass,
42-
useLegacyInjectDependenciesAttribute: useLegacyInjectDependenciesAttribute)
43-
.Configure(b =>
44-
{
45-
if (runInScope != null)
46-
{
47-
b.UseMiddleware((context, next) =>
48-
{
49-
using (runInScope(context))
50-
{
51-
return next(context);
52-
}
53-
}, MiddlewareStages.PreTokenize, int.MinValue + 10);
54-
}
55-
});
31+
return appRunner.UseDependencyResolver(new AutofacResolver(container),
32+
runInScope,
33+
argumentModelResolveStrategy,
34+
commandClassResolveStrategy,
35+
useLegacyInjectDependenciesAttribute);
5636
}
5737
}
5838
}
Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using CommandDotNet.Builders;
32
using CommandDotNet.Execution;
43

54
namespace CommandDotNet.IoC.MicrosoftDependencyInjection
@@ -10,17 +9,11 @@ public static class AppRunnerConfigurationExtensions
109
/// <param name="appRunner">the <see cref="AppRunner"/></param>
1110
/// <param name="serviceProvider">the <see cref="IServiceProvider"/> to use</param>
1211
/// <param name="runInScope">if provided, the scope will be created at the beginning of the run and disposed at the end</param>
13-
/// <param name="useResolveForArgumentModel">
14-
/// <see cref="IDependencyResolver.TryResolve"/> is the default to resolve <see cref="IArgumentModel"/>s.
15-
/// Set this to true to use <see cref="IDependencyResolver.Resolve"/>.
16-
/// If Resolve is used and returns null, this framework will attempt to
17-
/// instantiate an instance.
12+
/// <param name="argumentModelResolveStrategy">
13+
/// the <see cref="ResolveStrategy"/> used to resolve <see cref="IArgumentModel"/>s.
1814
/// </param>
19-
/// <param name="useTryResolveForCommandClass">
20-
/// <see cref="IDependencyResolver.Resolve"/> is the default to resolve command classes.
21-
/// Set this to true to use <see cref="IDependencyResolver.TryResolve"/>.
22-
/// If Resolve is used and returns null, this framework will attempt to
23-
/// instantiate an instance.
15+
/// <param name="commandClassResolveStrategy">
16+
/// the <see cref="ResolveStrategy"/> used to resolve command classes.
2417
/// </param>
2518
/// <param name="useLegacyInjectDependenciesAttribute">
2619
/// when true, resolve instances for properties marked with [InjectProperty].
@@ -30,28 +23,15 @@ public static AppRunner UseMicrosoftDependencyInjection(
3023
this AppRunner appRunner,
3124
IServiceProvider serviceProvider,
3225
Func<CommandContext, IDisposable> runInScope = null,
33-
bool useResolveForArgumentModel = false,
34-
bool useTryResolveForCommandClass = false,
26+
ResolveStrategy argumentModelResolveStrategy = ResolveStrategy.TryResolve,
27+
ResolveStrategy commandClassResolveStrategy = ResolveStrategy.Resolve,
3528
bool useLegacyInjectDependenciesAttribute = false)
3629
{
37-
return appRunner
38-
.UseDependencyResolver(new MicrosoftDependencyInjectionResolver(serviceProvider),
39-
useResolveForArgumentModel: useResolveForArgumentModel,
40-
useTryResolveForCommandClass: useTryResolveForCommandClass,
41-
useLegacyInjectDependenciesAttribute: useLegacyInjectDependenciesAttribute)
42-
.Configure(b =>
43-
{
44-
if (runInScope != null)
45-
{
46-
b.UseMiddleware((context, next) =>
47-
{
48-
using (runInScope(context))
49-
{
50-
return next(context);
51-
}
52-
}, MiddlewareStages.PreTokenize, int.MinValue + 10);
53-
}
54-
});
30+
return appRunner.UseDependencyResolver(new MicrosoftDependencyInjectionResolver(serviceProvider),
31+
runInScope,
32+
argumentModelResolveStrategy,
33+
commandClassResolveStrategy,
34+
useLegacyInjectDependenciesAttribute);
5535
}
5636
}
5737
}
Lines changed: 11 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System;
2-
using CommandDotNet.Builders;
32
using CommandDotNet.Execution;
43
using SimpleInjector;
54

@@ -11,17 +10,11 @@ public static class AppRunnerConfigurationExtensions
1110
/// <param name="appRunner">the <see cref="AppRunner"/></param>
1211
/// <param name="container">the SimpleInjector container to use</param>
1312
/// <param name="runInScope">if provided, the scope will be created at the beginning of the run and disposed at the end</param>
14-
/// <param name="useResolveForArgumentModel">
15-
/// <see cref="IDependencyResolver.TryResolve"/> is the default to resolve <see cref="IArgumentModel"/>s.
16-
/// Set this to true to use <see cref="IDependencyResolver.Resolve"/>.
17-
/// If Resolve is used and returns null, this framework will attempt to
18-
/// instantiate an instance.
13+
/// <param name="argumentModelResolveStrategy">
14+
/// the <see cref="ResolveStrategy"/> used to resolve <see cref="IArgumentModel"/>s.
1915
/// </param>
20-
/// <param name="useTryResolveForCommandClass">
21-
/// <see cref="IDependencyResolver.Resolve"/> is the default to resolve command classes.
22-
/// Set this to true to use <see cref="IDependencyResolver.TryResolve"/>.
23-
/// If Resolve is used and returns null, this framework will attempt to
24-
/// instantiate an instance.
16+
/// <param name="commandClassResolveStrategy">
17+
/// the <see cref="ResolveStrategy"/> used to resolve command classes.
2518
/// </param>
2619
/// <param name="useLegacyInjectDependenciesAttribute">
2720
/// when true, resolve instances for properties marked with [InjectProperty].
@@ -31,28 +24,15 @@ public static AppRunner UseSimpleInjector(
3124
this AppRunner appRunner,
3225
Container container,
3326
Func<CommandContext, IDisposable> runInScope = null,
34-
bool useResolveForArgumentModel = false,
35-
bool useTryResolveForCommandClass = false,
27+
ResolveStrategy argumentModelResolveStrategy = ResolveStrategy.TryResolve,
28+
ResolveStrategy commandClassResolveStrategy = ResolveStrategy.Resolve,
3629
bool useLegacyInjectDependenciesAttribute = false)
3730
{
38-
return appRunner
39-
.UseDependencyResolver(new SimpleInjectorResolver(container),
40-
useResolveForArgumentModel: useResolveForArgumentModel,
41-
useTryResolveForCommandClass: useTryResolveForCommandClass,
42-
useLegacyInjectDependenciesAttribute: useLegacyInjectDependenciesAttribute)
43-
.Configure(b =>
44-
{
45-
if (runInScope != null)
46-
{
47-
b.UseMiddleware((context, next) =>
48-
{
49-
using (runInScope(context))
50-
{
51-
return next(context);
52-
}
53-
}, MiddlewareStages.PreTokenize, int.MinValue + 10);
54-
}
55-
});
31+
return appRunner.UseDependencyResolver(new SimpleInjectorResolver(container),
32+
runInScope,
33+
argumentModelResolveStrategy,
34+
commandClassResolveStrategy,
35+
useLegacyInjectDependenciesAttribute);
5636
}
5737
}
5838
}

CommandDotNet.Tests/CommandDotNet.FluentValidation/ModelValidationTests.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
using CommandDotNet.Execution;
12
using CommandDotNet.FluentValidation;
23
using CommandDotNet.TestTools;
34
using CommandDotNet.TestTools.Scenarios;
@@ -80,7 +81,7 @@ public void Exec_WithInvalidData_PrintsValidationError_UsingValidatorFromDI()
8081
.UseFluentValidation()
8182
.UseDependencyResolver(
8283
new TestDependencyResolver{new PersonValidator()},
83-
useTryResolveForCommandClass: true)
84+
commandClassResolveStrategy: ResolveStrategy.TryResolve)
8485
.VerifyScenario(TestOutputHelper, scenario);
8586
}
8687

@@ -96,8 +97,8 @@ public void Exec_WithValidData_Succeeds()
9697
new AppRunner<App>()
9798
.UseFluentValidation()
9899
.UseDependencyResolver(
99-
new TestDependencyResolver { new PersonValidator() },
100-
useTryResolveForCommandClass: true)
100+
new TestDependencyResolver { new PersonValidator() },
101+
commandClassResolveStrategy: ResolveStrategy.TryResolve)
101102
.VerifyScenario(TestOutputHelper, scenario);
102103
}
103104

@@ -135,8 +136,8 @@ public void Exec_WhenValidatorNotRegistered_ValidatorIsCreated()
135136
new AppRunner<App>()
136137
.UseFluentValidation()
137138
.UseDependencyResolver(
138-
new TestDependencyResolver(),
139-
useTryResolveForCommandClass: true)
139+
new TestDependencyResolver(),
140+
commandClassResolveStrategy: ResolveStrategy.TryResolve)
140141
.VerifyScenario(TestOutputHelper, scenario);
141142
}
142143

@@ -162,7 +163,7 @@ public void Exec_WhenInvalidValidator_PrintsError()
162163
.UseFluentValidation()
163164
.UseDependencyResolver(
164165
new TestDependencyResolver(),
165-
useTryResolveForCommandClass: true)
166+
commandClassResolveStrategy: ResolveStrategy.TryResolve)
166167
.VerifyScenario(TestOutputHelper, scenario);
167168
}
168169

CommandDotNet.Tests/CommandDotNet.IoC/ResolveConfigurationTests.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using CommandDotNet.Execution;
23
using CommandDotNet.TestTools;
34
using FluentAssertions;
45
using Xunit;
@@ -29,7 +30,7 @@ public void CommandClass_DefaultUses_Resolve()
2930
public void CommandClass_CanConfigureToUse_TryResolve()
3031
{
3132
new AppRunner<App>()
32-
.UseDependencyResolver(new TestDependencyResolver(), useTryResolveForCommandClass: true)
33+
.UseDependencyResolver(new TestDependencyResolver(), commandClassResolveStrategy: ResolveStrategy.TryResolve)
3334
.RunInMem("Do", _testOutputHelper)
3435
.ExitCode.Should().Be(0);
3536
}
@@ -47,7 +48,7 @@ public void ArgumentModel_DefaultUses_TryResolve()
4748
public void ArgumentModel_CanConfigureToUse_Resolve()
4849
{
4950
Assert.Throws<Exception>(() => new AppRunner<App>()
50-
.UseDependencyResolver(new TestDependencyResolver { new App() }, useResolveForArgumentModel: true)
51+
.UseDependencyResolver(new TestDependencyResolver { new App() }, argumentModelResolveStrategy: ResolveStrategy.Resolve)
5152
.Run(new[] { "Do" }))
5253
.Message.Should().Contain(
5354
"Dependency not registered: CommandDotNet.Tests.CommandDotNet.IoC.ResolveConfigurationTests+ArgModel");

CommandDotNet/AppRunnerConfigExtensions.cs

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,17 +71,12 @@ public static AppRunner AppendPipedInputToOperandList(this AppRunner appRunner)
7171
/// <summary>Use the <see cref="IDependencyResolver"/> to create the command classes.</summary>
7272
/// <param name="appRunner">the <see cref="AppRunner"/> instance</param>
7373
/// <param name="dependencyResolver">the <see cref="IDependencyResolver"/> to use</param>
74-
/// <param name="useResolveForArgumentModel">
75-
/// <see cref="IDependencyResolver.TryResolve"/> is the default to resolve <see cref="IArgumentModel"/>s.
76-
/// Set this to true to use <see cref="IDependencyResolver.Resolve"/>.
77-
/// If Resolve is used and returns null, this framework will attempt to
78-
/// instantiate an instance.
74+
/// <param name="runInScope">if provided, the scope will be created at the beginning of the run and disposed at the end</param>
75+
/// <param name="argumentModelResolveStrategy">
76+
/// the <see cref="ResolveStrategy"/> used to resolve <see cref="IArgumentModel"/>s.
7977
/// </param>
80-
/// <param name="useTryResolveForCommandClass">
81-
/// <see cref="IDependencyResolver.Resolve"/> is the default to resolve command classes.
82-
/// Set this to true to use <see cref="IDependencyResolver.TryResolve"/>.
83-
/// If Resolve is used and returns null, this framework will attempt to
84-
/// instantiate an instance.
78+
/// <param name="commandClassResolveStrategy">
79+
/// the <see cref="ResolveStrategy"/> used to resolve command classes.
8580
/// </param>
8681
/// <param name="useLegacyInjectDependenciesAttribute">
8782
/// when true, resolve instances for properties marked with [InjectProperty].
@@ -90,12 +85,29 @@ public static AppRunner AppendPipedInputToOperandList(this AppRunner appRunner)
9085
public static AppRunner UseDependencyResolver(
9186
this AppRunner appRunner,
9287
IDependencyResolver dependencyResolver,
93-
bool useResolveForArgumentModel = false,
94-
bool useTryResolveForCommandClass = false,
88+
Func<CommandContext, IDisposable> runInScope = null,
89+
ResolveStrategy argumentModelResolveStrategy = ResolveStrategy.TryResolve,
90+
ResolveStrategy commandClassResolveStrategy = ResolveStrategy.Resolve,
9591
bool useLegacyInjectDependenciesAttribute = false)
9692
{
97-
return DependencyResolverMiddleware.UseDependencyResolver(appRunner, dependencyResolver,
98-
useResolveForArgumentModel, useTryResolveForCommandClass, useLegacyInjectDependenciesAttribute);
93+
DependencyResolverMiddleware.UseDependencyResolver(appRunner, dependencyResolver,
94+
argumentModelResolveStrategy, commandClassResolveStrategy, useLegacyInjectDependenciesAttribute);
95+
96+
if (runInScope != null)
97+
{
98+
appRunner.Configure(b =>
99+
{
100+
b.UseMiddleware((context, next) =>
101+
{
102+
using (runInScope(context))
103+
{
104+
return next(context);
105+
}
106+
}, MiddlewareStages.PreTokenize, int.MinValue + 10);
107+
});
108+
}
109+
110+
return appRunner;
99111
}
100112

101113
/// <summary>

CommandDotNet/Builders/DependencyResolverMiddleware.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,17 +8,17 @@ namespace CommandDotNet.Builders
88
internal static class DependencyResolverMiddleware
99
{
1010
internal static AppRunner UseDependencyResolver(AppRunner appRunner, IDependencyResolver dependencyResolver,
11-
bool useResolveForArgumentModel,
12-
bool useTryResolveForCommandClass,
11+
ResolveStrategy argumentModelResolveStrategy,
12+
ResolveStrategy commandClassResolveStrategy,
1313
bool useLegacyInjectDependenciesAttribute)
1414
{
1515
return appRunner.Configure(c =>
1616
{
1717
c.DependencyResolver = dependencyResolver;
1818
c.Services.Add(new ResolverService
1919
{
20-
UseResolveForArgumentModel = useResolveForArgumentModel,
21-
UseTryResolveForCommandClass = useTryResolveForCommandClass
20+
ArgumentModelResolveStrategy = argumentModelResolveStrategy,
21+
CommandClassResolveStrategy = commandClassResolveStrategy
2222
});
2323
if (useLegacyInjectDependenciesAttribute)
2424
{
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
using CommandDotNet.Builders;
2+
3+
namespace CommandDotNet.Execution
4+
{
5+
/// <summary>
6+
/// Specifies whether <see cref="IDependencyResolver.Resolve"/> or <see cref="IDependencyResolver.TryResolve"/> is used.
7+
/// When Resolve is used, if the the Resolve method returns null instead of throwing an exception,
8+
/// the framework will attempt to instantiate an instance of the type.
9+
/// </summary>
10+
public enum ResolveStrategy
11+
{
12+
Resolve,
13+
TryResolve
14+
}
15+
}

0 commit comments

Comments
 (0)