Skip to content

Commit cf4c91b

Browse files
committed
Refactored basic behaviour to stand-alone project
Upgraded to .NET Standard 2.0
1 parent eea05f7 commit cf4c91b

File tree

5 files changed

+63
-28
lines changed

5 files changed

+63
-28
lines changed

Conker.sln

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11

22
Microsoft Visual Studio Solution File, Format Version 12.00
33
# Visual Studio 15
4-
VisualStudioVersion = 15.0.26430.16
4+
VisualStudioVersion = 15.0.26730.10
55
MinimumVisualStudioVersion = 10.0.40219.1
6-
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Conker", "src\Conker\Conker.csproj", "{A3ED62B0-6AFF-47F4-B2E7-A615D1555089}"
6+
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Conker", "src\Conker\Conker.csproj", "{A3ED62B0-6AFF-47F4-B2E7-A615D1555089}"
77
EndProject
88
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Conker.Spec", "test\Conker.Spec\Conker.Spec.csproj", "{DCC6B80B-FF54-4564-80CF-0C8F5E89C256}"
99
EndProject
@@ -25,4 +25,7 @@ Global
2525
GlobalSection(SolutionProperties) = preSolution
2626
HideSolutionNode = FALSE
2727
EndGlobalSection
28+
GlobalSection(ExtensibilityGlobals) = postSolution
29+
SolutionGuid = {BC106EF0-0A89-4E73-99F9-04978EEC4BA8}
30+
EndGlobalSection
2831
EndGlobal

src/Conker/Application.cs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Reflection;
4+
5+
namespace Conker
6+
{
7+
public class Application
8+
{
9+
private readonly Dictionary<string, (MethodInfo method, object target)> _commands
10+
= new Dictionary<string, (MethodInfo method, object target)>();
11+
12+
public void AddCommand(string commandName, Action cmd)
13+
{
14+
_commands.Add(commandName, (cmd.Method, cmd.Target));
15+
}
16+
17+
public void AddCommand(string commandName, MethodInfo handlerMethod, object target)
18+
{
19+
_commands.Add(commandName, (handlerMethod, target));
20+
}
21+
22+
public void Execute(IReadOnlyList<string> args)
23+
{
24+
var handler = _commands[args[0]];
25+
26+
var arguments = new object[args.Count - 1];
27+
28+
// Convert argument strings to expected types.
29+
var parameters = handler.method.GetParameters();
30+
31+
for (var i = 0; i < parameters.Length; i++)
32+
{
33+
arguments[i] = Convert.ChangeType(args[i + 1], parameters[i].ParameterType);
34+
}
35+
36+
handler.method.Invoke(handler.target, arguments);
37+
}
38+
}
39+
}

src/Conker/Conker.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
<Project Sdk="Microsoft.NET.Sdk">
22

33
<PropertyGroup>
4-
<TargetFramework>netstandard1.4</TargetFramework>
4+
<TargetFramework>netstandard2.0</TargetFramework>
55
</PropertyGroup>
66

77
</Project>

test/Conker.Spec/CommandParsingSteps.cs

+16-25
Original file line numberDiff line numberDiff line change
@@ -37,14 +37,17 @@ protected void Invoke(object arg1, object arg2)
3737
}
3838
}
3939

40-
private readonly Dictionary<string, (MethodInfo method, object target)> _commands
41-
= new Dictionary<string, (MethodInfo method, object target)>();
42-
4340
private string _invokedCommandName;
4441

45-
private CommandHandler _commandHandler;
42+
private CommandParsingSteps.CommandHandler _commandHandler;
4643

4744
private static readonly Regex Whitespace = new Regex("\\s+");
45+
private readonly Application _application;
46+
47+
public CommandParsingSteps()
48+
{
49+
_application = new Application();
50+
}
4851

4952
[Given(@"I have a handler for the command ""(.*)"" which doesn't take arguments")]
5053
public void GivenIHaveAHandlerForTheCommandWhichDoesnTTakeArguments(string commandName)
@@ -53,29 +56,17 @@ public void GivenIHaveAHandlerForTheCommandWhichDoesnTTakeArguments(string comma
5356

5457
Action cmd = Command;
5558

56-
_commands.Add(commandName, (cmd.Method, cmd.Target));
59+
_application.AddCommand(commandName, cmd);
5760
}
58-
61+
5962
[When(@"I run my application with the args ""(.*)""")]
6063
public void WhenIRunMyApplicationWithTheArgs(string args)
6164
{
6265
var values = Whitespace.Split(args);
6366

64-
var handler = _commands[values[0]];
65-
66-
var arguments = new object[values.Length - 1];
67-
68-
// Convert argument strings to expected types.
69-
var parameters = handler.method.GetParameters();
70-
71-
for (var i = 0; i < parameters.Length; i++)
72-
{
73-
arguments[i] = Convert.ChangeType(values[i + 1], parameters[i].ParameterType);
74-
}
75-
76-
handler.method.Invoke(handler.target, arguments);
67+
_application.Execute(values);
7768
}
78-
69+
7970
[Then(@"the ""(.*)"" command is invoked")]
8071
public void ThenTheCommandIsInvoked(string commandName)
8172
{
@@ -110,7 +101,7 @@ public void GivenIHaveAHandlerForTheCommandWhichTakesTheFollowingArguments(strin
110101
var typeBuilder = moduleBuilder.DefineType(
111102
"DynamicCommandHandler",
112103
TypeAttributes.Public | TypeAttributes.Class,
113-
typeof(CommandHandler));
104+
typeof(CommandParsingSteps.CommandHandler));
114105

115106
var constructorBuilder = typeBuilder.DefineConstructor(
116107
MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName,
@@ -119,7 +110,7 @@ public void GivenIHaveAHandlerForTheCommandWhichTakesTheFollowingArguments(strin
119110

120111
var constructorBodyGenerator = constructorBuilder.GetILGenerator();
121112

122-
var baseCtor = typeof(CommandHandler).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).Single();
113+
var baseCtor = typeof(CommandParsingSteps.CommandHandler).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance).Single();
123114
constructorBodyGenerator.Emit(OpCodes.Ldarg_0);
124115
constructorBodyGenerator.Emit(OpCodes.Ldarg_1);
125116
constructorBodyGenerator.Emit(OpCodes.Call, baseCtor);
@@ -153,7 +144,7 @@ public void GivenIHaveAHandlerForTheCommandWhichTakesTheFollowingArguments(strin
153144
}
154145

155146
// Call the protected "Invoke" method to save the arguments.
156-
var captureMethod = typeof(CommandHandler)
147+
var captureMethod = typeof(CommandParsingSteps.CommandHandler)
157148
.GetMethods(BindingFlags.Instance | BindingFlags.NonPublic)
158149
.Where(method => method.Name == "Invoke")
159150
.Single(method => method.GetParameters().Length == parameters.Length);
@@ -167,11 +158,11 @@ public void GivenIHaveAHandlerForTheCommandWhichTakesTheFollowingArguments(strin
167158

168159
void Command() => _invokedCommandName = commandName;
169160

170-
_commandHandler = (CommandHandler)Activator.CreateInstance(handlerType, (Action)Command);
161+
_commandHandler = (CommandParsingSteps.CommandHandler)Activator.CreateInstance(handlerType, (Action)Command);
171162

172163
var handlerMethod = handlerType.GetMethod("Handle");
173164

174-
_commands.Add(commandName, (handlerMethod, _commandHandler));
165+
_application.AddCommand(commandName, handlerMethod, _commandHandler);
175166
}
176167

177168
[Then(@"the ""(.*)"" command is invoked with the following arguments")]

test/Conker.Spec/Conker.Spec.csproj

+2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
<ReferencePath>$(ProgramFiles)\Common Files\microsoft shared\VSTT\$(VisualStudioVersion)\UITestExtensionPackages</ReferencePath>
1818
<IsCodedUITest>False</IsCodedUITest>
1919
<TestProjectType>UnitTest</TestProjectType>
20+
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
21+
<GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
2022
<NuGetPackageImportStamp>
2123
</NuGetPackageImportStamp>
2224
<TargetFrameworkProfile />

0 commit comments

Comments
 (0)