This is my solution to the Clear Measure Code Challenge.
The challenge is to create a NuGet package for others to consume that:
- Returns back a list of strings based on the number of items specified, where the string corresponds to the item's index.
- Allows the consumer to specify a list of number-string pairs, where if the index is divisible by the number, the string is returned instead of the index.
- If the index is divisible by more than one number, the strings are concatenated together in the order they were provided.
We also want to create a build script that can be used to build the NuGet package and run tests locally.
To view the code, open the CodeChallenge.sln solution in Visual Studio.
Assuming the CodeChallenge.Console
project is set as the startup project, you can run the app to see the sample output produced by the Program.cs file.
The main library is the CustomerItems
project, which contains the ItemsRetriever
class and IMapItems
interface.
The EvenlyDivisibleItemMapper
class is the default implementation of the IMapItems
interface, and is used to satisfy the requirements of the challenge.
Other implementations of the IMapItems
interface can be created to provide different functionality though, as shown in the docs down below, and in the console application's Program.cs.
The CustomerItems.UnitTests
project contains unit tests for both the ItemsRetriever
and EvenlyDivisibleItemMapper
classes.
You can build and test the application by running the build.ps1
script in the root of the repository.
Once you have the CustomerItems
NuGet package installed in your project, you can use the default EvenlyDivisibleItemMapper
class to map items, like this:
List<ItemMapping> mappings = new()
{
new ItemMapping(3, "DivisibleBy3"),
new ItemMapping(5, "DivisibleBy5"),
new ItemMapping(10, "DivisibleBy10"),
};
var itemMapper = new EvenlyDivisibleItemMapper(mappings)
var app = new ItemsRetriever(itemMapper);
var items = app.GetItems(100);
items
will contain a list of 100 strings, where the string is the item number if it is not evenly divisible by any of the numbers in the mappings, or the concatenated strings of the mappings if it is.
Sample output of items
:
1
2
DivisibleBy3
4
DivisibleBy5
DivisibleBy3
7
8
DivisibleBy3
DivisibleBy5 DivisibleBy10
11
...
You can create your own mappings
list with as many or as few ItemMapping
s as you like.
If you do not want items returned based on if the index is evenly divisible by a number, you can create your own item mapper by implementing the IMapItems
interface.
This was not required by the challenge, but shows that the library is extensible, allowing future use cases to be more easily supported.
Here is an example of an item mapper that returns the letter of the alphabet that corresponds to the number provided:
public class AlphabetItemMapper : IMapItems
{
public string MapItem(int number)
{
// Return the letter of the alphabet that corresponds to the number passed in.
return ((char)((number % 26) + 64)).ToString();
}
}
You can then use this item mapper in the ItemsRetriever
class like this:
var alphabetItemRetriever = new ItemsRetriever(new AlphabetItemMapper());
var letters = alphabetItemRetriever.GetItems(100);
Sample output of letters
:
A
B
C
D
E
F
...
See the Contributing page for details on building and running the application.
See what's changed in the application over time by viewing the changelog.
A list of potential improvements to make if the project were to grow in complexity and criticality:
- Allow the
ItemsRetriever
class to take aMicrosoft.Extensions.Logging.ILogger
in the constructor to log messages.- Similarly, could implement OpenTelemetry to emit traces and metrics.
- Setup an automated CI/CD pipeline to build and test the application automatically from GitHub.
- Create integration tests to test the application end-to-end, including using a .NET Framework application to ensure the library stays backwards compatible.
- Create post-deployment smoke tests that actually download and install the real NuGet package to ensure it works as expected.
- Create a runbook for the application to help with troubleshooting and maintenance.
- Create an architecture diagram to show how the application is structured.