Skip to content

Commit a8a6dd0

Browse files
committed
refactor: use IHostEnvironment instead of Environment variables (#320)
Replace Environment.GetEnvironmentVariable with IHostEnvironment in PlayerService for environment detection. This aligns with ASP.NET Core best practices and matches the pattern used in ExceptionMiddleware. Changes: - Inject IHostEnvironment into PlayerService constructor - Replace string-based environment check with environment.IsDevelopment() - Remove AspNetCore_Environment and Development constants - Update PlayerMocks to include IHostEnvironment mock - Update all PlayerServiceTests to use new mock pattern
1 parent 7657bc9 commit a8a6dd0

3 files changed

Lines changed: 36 additions & 42 deletions

File tree

src/Dotnet.Samples.AspNetCore.WebApi/Services/PlayerService.cs

Lines changed: 3 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ public class PlayerService(
99
IPlayerRepository playerRepository,
1010
ILogger<PlayerService> logger,
1111
IMemoryCache memoryCache,
12-
IMapper mapper
12+
IMapper mapper,
13+
IHostEnvironment environment
1314
) : IPlayerService
1415
{
1516
/// <summary>
@@ -27,20 +28,6 @@ IMapper mapper
2728
/// </summary>
2829
private static readonly string CacheKey_RetrieveAsync = nameof(RetrieveAsync);
2930

30-
/// <summary>
31-
/// The key used to store the environment variable for ASP.NET Core.
32-
/// <br/>
33-
/// <see href="https://learn.microsoft.com/en-us/aspnet/core/fundamentals/environments?view=aspnetcore-8.0">
34-
/// Use multiple environments in ASP.NET Core
35-
/// </see>
36-
/// </summary>
37-
private static readonly string AspNetCore_Environment = "ASPNETCORE_ENVIRONMENT";
38-
39-
/// <summary>
40-
/// The value used to check if the environment is Development.
41-
/// </summary>
42-
private static readonly string Development = "Development";
43-
4431
/* -------------------------------------------------------------------------
4532
* Create
4633
* ---------------------------------------------------------------------- */
@@ -68,7 +55,7 @@ public async Task<List<PlayerResponseModel>> RetrieveAsync()
6855
}
6956
else
7057
{
71-
if (Environment.GetEnvironmentVariable(AspNetCore_Environment) == Development)
58+
if (environment.IsDevelopment())
7259
{
7360
await SimulateRepositoryDelayAsync();
7461
}

test/Dotnet.Samples.AspNetCore.WebApi.Tests/Unit/PlayerServiceTests.cs

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,6 @@ public class PlayerServiceTests : IDisposable
1111
{
1212
private bool _disposed;
1313

14-
public PlayerServiceTests()
15-
{
16-
Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", "Development");
17-
}
18-
1914
/* -------------------------------------------------------------------------
2015
* Create
2116
* ---------------------------------------------------------------------- */
@@ -27,14 +22,15 @@ public async Task GivenCreateAsync_WhenRepositoryAddAsync_ThenAddsPlayerToReposi
2722
// Arrange
2823
var request = PlayerFakes.MakeRequestModelForCreate();
2924
var response = PlayerFakes.MakeResponseModelForCreate();
30-
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
25+
var (repository, logger, memoryCache, mapper, environment) = PlayerMocks.InitServiceMocks();
3126
mapper.Setup(mapper => mapper.Map<PlayerResponseModel>(request)).Returns(response);
3227

3328
var service = new PlayerService(
3429
repository.Object,
3530
logger.Object,
3631
memoryCache.Object,
37-
mapper.Object
32+
mapper.Object,
33+
environment.Object
3834
);
3935

4036
// Act
@@ -61,15 +57,16 @@ public async Task GivenRetrieveAsync_WhenRepositoryGetAllAsyncReturnsPlayers_The
6157
var value = It.IsAny<object>();
6258
var players = PlayerFakes.MakeStarting11();
6359
var response = PlayerFakes.MakeResponseModelsForRetrieve();
64-
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
60+
var (repository, logger, memoryCache, mapper, environment) = PlayerMocks.InitServiceMocks();
6561
repository.Setup(repository => repository.GetAllAsync()).ReturnsAsync(players);
6662
mapper.Setup(mapper => mapper.Map<List<PlayerResponseModel>>(players)).Returns(response);
6763

6864
var service = new PlayerService(
6965
repository.Object,
7066
logger.Object,
7167
memoryCache.Object,
72-
mapper.Object
68+
mapper.Object,
69+
environment.Object
7370
);
7471

7572
// Act
@@ -94,15 +91,16 @@ public async Task GivenRetrieveAsync_WhenExecutedForTheSecondTime_ThenSecondExec
9491
var value = It.IsAny<object>();
9592
var players = PlayerFakes.MakeStarting11();
9693
var response = PlayerFakes.MakeResponseModelsForRetrieve();
97-
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
94+
var (repository, logger, memoryCache, mapper, environment) = PlayerMocks.InitServiceMocks();
9895
repository.Setup(repository => repository.GetAllAsync()).ReturnsAsync(players);
9996
mapper.Setup(mapper => mapper.Map<List<PlayerResponseModel>>(players)).Returns(response);
10097

10198
var service = new PlayerService(
10299
repository.Object,
103100
logger.Object,
104101
memoryCache.Object,
105-
mapper.Object
102+
mapper.Object,
103+
environment.Object
106104
);
107105

108106
// Act
@@ -129,14 +127,15 @@ public async Task GivenRetrieveByIdAsync_WhenRepositoryFindByIdAsyncReturnsNull_
129127
{
130128
// Arrange
131129
var id = Guid.NewGuid();
132-
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
130+
var (repository, logger, memoryCache, mapper, environment) = PlayerMocks.InitServiceMocks();
133131
repository.Setup(repository => repository.FindByIdAsync(id)).ReturnsAsync(null as Player);
134132

135133
var service = new PlayerService(
136134
repository.Object,
137135
logger.Object,
138136
memoryCache.Object,
139-
mapper.Object
137+
mapper.Object,
138+
environment.Object
140139
);
141140

142141
// Act
@@ -157,15 +156,16 @@ public async Task GivenRetrieveByIdAsync_WhenRepositoryFindByIdAsyncReturnsPlaye
157156
var squadNumber = 10;
158157
var player = PlayerFakes.MakeFromStarting11(squadNumber);
159158
var response = PlayerFakes.MakeResponseModelForRetrieve(squadNumber);
160-
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
159+
var (repository, logger, memoryCache, mapper, environment) = PlayerMocks.InitServiceMocks();
161160
repository.Setup(repository => repository.FindByIdAsync(id)).ReturnsAsync(player);
162161
mapper.Setup(mapper => mapper.Map<PlayerResponseModel>(player)).Returns(response);
163162

164163
var service = new PlayerService(
165164
repository.Object,
166165
logger.Object,
167166
memoryCache.Object,
168-
mapper.Object
167+
mapper.Object,
168+
environment.Object
169169
);
170170

171171
// Act
@@ -184,7 +184,7 @@ public async Task GivenRetrieveBySquadNumberAsync_WhenRepositoryFindBySquadNumbe
184184
{
185185
// Arrange
186186
var squadNumber = 999;
187-
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
187+
var (repository, logger, memoryCache, mapper, environment) = PlayerMocks.InitServiceMocks();
188188
repository
189189
.Setup(repository => repository.FindBySquadNumberAsync(squadNumber))
190190
.ReturnsAsync(null as Player);
@@ -193,7 +193,8 @@ public async Task GivenRetrieveBySquadNumberAsync_WhenRepositoryFindBySquadNumbe
193193
repository.Object,
194194
logger.Object,
195195
memoryCache.Object,
196-
mapper.Object
196+
mapper.Object,
197+
environment.Object
197198
);
198199

199200
// Act
@@ -216,7 +217,7 @@ public async Task GivenRetrieveBySquadNumberAsync_WhenRepositoryFindBySquadNumbe
216217
var squadNumber = 10;
217218
var player = PlayerFakes.MakeFromStarting11(squadNumber);
218219
var response = PlayerFakes.MakeResponseModelForRetrieve(squadNumber);
219-
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
220+
var (repository, logger, memoryCache, mapper, environment) = PlayerMocks.InitServiceMocks();
220221
repository
221222
.Setup(repository => repository.FindBySquadNumberAsync(squadNumber))
222223
.ReturnsAsync(player);
@@ -226,7 +227,8 @@ public async Task GivenRetrieveBySquadNumberAsync_WhenRepositoryFindBySquadNumbe
226227
repository.Object,
227228
logger.Object,
228229
memoryCache.Object,
229-
mapper.Object
230+
mapper.Object,
231+
environment.Object
230232
);
231233

232234
// Act
@@ -254,7 +256,7 @@ public async Task GivenUpdateAsync_WhenRepositoryFindBySquadNumberAsyncReturnsPl
254256
var squadNumber = 23;
255257
var player = PlayerFakes.MakeFromStarting11(squadNumber);
256258
var request = PlayerFakes.MakeRequestModelForUpdate(squadNumber);
257-
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
259+
var (repository, logger, memoryCache, mapper, environment) = PlayerMocks.InitServiceMocks();
258260
repository
259261
.Setup(repository => repository.FindBySquadNumberAsync(squadNumber))
260262
.ReturnsAsync(player);
@@ -263,7 +265,8 @@ public async Task GivenUpdateAsync_WhenRepositoryFindBySquadNumberAsyncReturnsPl
263265
repository.Object,
264266
logger.Object,
265267
memoryCache.Object,
266-
mapper.Object
268+
mapper.Object,
269+
environment.Object
267270
);
268271

269272
// Act
@@ -293,7 +296,7 @@ public async Task GivenDeleteAsync_WhenRepositoryFindBySquadNumberAsyncReturnsPl
293296
// Arrange
294297
var squadNumber = 26;
295298
var player = PlayerFakes.MakeFromStarting11(squadNumber);
296-
var (repository, logger, memoryCache, mapper) = PlayerMocks.InitServiceMocks();
299+
var (repository, logger, memoryCache, mapper, environment) = PlayerMocks.InitServiceMocks();
297300
repository
298301
.Setup(repository => repository.FindBySquadNumberAsync(squadNumber))
299302
.ReturnsAsync(player);
@@ -302,7 +305,8 @@ public async Task GivenDeleteAsync_WhenRepositoryFindBySquadNumberAsyncReturnsPl
302305
repository.Object,
303306
logger.Object,
304307
memoryCache.Object,
305-
mapper.Object
308+
mapper.Object,
309+
environment.Object
306310
);
307311

308312
// Act
@@ -332,7 +336,6 @@ protected virtual void Dispose(bool disposing)
332336
{
333337
if (!_disposed)
334338
{
335-
Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", null);
336339
_disposed = true;
337340
}
338341
}

test/Dotnet.Samples.AspNetCore.WebApi.Tests/Utilities/PlayerMocks.cs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Microsoft.AspNetCore.Mvc;
88
using Microsoft.AspNetCore.Mvc.Routing;
99
using Microsoft.Extensions.Caching.Memory;
10+
using Microsoft.Extensions.Hosting;
1011
using Microsoft.Extensions.Logging;
1112
using Moq;
1213

@@ -46,14 +47,17 @@ public static (
4647
Mock<IPlayerRepository> repository,
4748
Mock<ILogger<PlayerService>> logger,
4849
Mock<IMemoryCache> memoryCache,
49-
Mock<IMapper> mapper
50+
Mock<IMapper> mapper,
51+
Mock<IHostEnvironment> environment
5052
) InitServiceMocks(object? cacheValue = null)
5153
{
5254
var repository = new Mock<IPlayerRepository>();
5355
var logger = new Mock<ILogger<PlayerService>>();
5456
var memoryCache = SetupMemoryCacheMock(cacheValue ?? It.IsAny<object>());
5557
var mapper = new Mock<IMapper>();
56-
return (repository, logger, memoryCache, mapper);
58+
var environment = new Mock<IHostEnvironment>();
59+
environment.Setup(env => env.EnvironmentName).Returns("Development");
60+
return (repository, logger, memoryCache, mapper, environment);
5761
}
5862

5963
public static Mock<IMemoryCache> SetupMemoryCacheMock(object? value)

0 commit comments

Comments
 (0)