Skip to content

Commit

Permalink
Use DI for DieController
Browse files Browse the repository at this point in the history
  • Loading branch information
mspons committed Aug 23, 2016
1 parent 16e5e40 commit e3ef64b
Show file tree
Hide file tree
Showing 7 changed files with 45 additions and 28 deletions.
26 changes: 9 additions & 17 deletions src/DiceApi.Core/Die.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,17 @@

namespace DiceApi.Core
{
public class Die
public class Die : IRollable
{
/// <summary>
/// Initializes a new instance of <see cref="Die" /> with a
/// specified number of sides.
/// </summary>
/// <param name="sides">Number of sides on the die.</param>
public Die(int sides)
public Die()
{
if (sides < 1) {
throw new ArgumentOutOfRangeException(nameof(sides));
}

this.Sides = sides;

this.RandomNumberGenerator = new Random();
}

/// <summary>
/// Gets the number of sides on the die.
/// </summary>
/// <returns></returns>
public int Sides { get; }

/// <summary>
/// Gets an instance of Random that we instantiate with the Die
/// constructor. This is used by Roll() to create a random value
Expand All @@ -36,11 +23,16 @@ public Die(int sides)
/// <summary>
/// Rolls the die, returning its value.
/// </summary>
/// <param name="sides">Number of sides on the die.</param>
/// <returns>Result of die roll.</returns>
public int Roll()
public int Roll(int sides)
{
if (sides < 1) {
throw new ArgumentOutOfRangeException(nameof(sides));
}

// Range for Next() is inclusive on the minimum, exclusive on the maximum
return this.RandomNumberGenerator.Next(1, this.Sides + 1);
return this.RandomNumberGenerator.Next(1, sides + 1);
}
}
}
7 changes: 7 additions & 0 deletions src/DiceApi.Core/IRollable.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace DiceApi.Core
{
public interface IRollable
{
int Roll(int sides);
}
}
13 changes: 9 additions & 4 deletions src/DiceApi.WebApi/Controllers/DieController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,14 @@ namespace DiceApi.WebApi.Controllers
{
[Route("api/[controller]")]
public class DieController : Controller
{
{
private IRollable Die { get; }

public DieController(IRollable die)
{
this.Die = die;
}

// GET api/die
[HttpGet]
public IActionResult Get([FromQuery] int sides)
Expand All @@ -21,10 +28,8 @@ public IActionResult Get([FromQuery] int sides)
{
return this.BadRequest();
}

var die = new Die(sides);

return this.Ok(die.Roll());
return this.Ok(this.Die.Roll(sides));
}
}
}
7 changes: 7 additions & 0 deletions src/DiceApi.WebApi/Startup.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

using DiceApi.Core;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
Expand Down Expand Up @@ -29,6 +31,11 @@ public void ConfigureServices(IServiceCollection services)
{
// Add framework services.
services.AddMvc();

// Register Die class as IRollable with DI container, doing this as singleton
// since we want to have the same Random instance performing all our random
// number generation.
services.AddSingleton<IRollable, Die>();
}

// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
Expand Down
9 changes: 5 additions & 4 deletions test/DiceApi.Core.Tests/DieTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ public class DieTest
/// an invalid number of sides.
/// </summary>
[Fact]
public void Constructor_GivenZeroSides_ThrowsException()
public void Roll_GivenZeroSides_ThrowsException()
{
var exception = Record.Exception(() => new Die(0));
var die = new Die();
var exception = Record.Exception(() => die.Roll(0));

Assert.NotNull(exception);
Assert.IsType<ArgumentOutOfRangeException>(exception);
Expand All @@ -31,13 +32,13 @@ public void Constructor_GivenZeroSides_ThrowsException()
public void Roll_GivenValidSides_ReturnsValueWithinRange()
{
int sides = 6;
var die = new Die(sides);
var die = new Die();

// Naive brute force verification that we always get a correct value
// within range.
for (int i = 0; i < 100; i++)
{
var result = die.Roll();
var result = die.Roll(sides);

Assert.True(this.WithinRange(sides, result));
}
Expand Down
5 changes: 3 additions & 2 deletions test/DiceApi.WebApi.Tests/DieControllerTest.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Mvc;
using Xunit;

using DiceApi.Core;
using DiceApi.WebApi.Controllers;

namespace DiceApi.WebApi.Tests
Expand All @@ -18,7 +19,7 @@ public class DieControllerTest
[Fact]
public void Get_GivenSidesLessThanZero_ReturnsBadRequestResult()
{
var sut = new DieController();
var sut = new DieController(new Die());

var result = sut.Get(-1);

Expand All @@ -32,7 +33,7 @@ public void Get_GivenSidesLessThanZero_ReturnsBadRequestResult()
[Fact]
public void Get_GivenValidSizeValue_ReturnsOkResult()
{
var sut = new DieController();
var sut = new DieController(new Die());

var result = sut.Get(6);

Expand Down
6 changes: 5 additions & 1 deletion test/DiceApi.WebApi.Tests/project.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@
"DiceApi.WebApi": {
"version":"1.0.0",
"target":"project"
}
},
"DiceApi.Core": {
"version":"1.0.0",
"target":"project"
}
},
"frameworks": {
"netcoreapp1.0": {
Expand Down

0 comments on commit e3ef64b

Please sign in to comment.