Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/run_unit_tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
- name: Setup .NET Core SDK
uses: actions/setup-dotnet@v1
with:
dotnet-version: 8.x
dotnet-version: 9.x

- name: Restore dependencies
run: dotnet restore src/IssueManager.sln
Expand Down
12 changes: 10 additions & 2 deletions src/IssueManager.Api/IssueManager.Api.csproj
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
<UserSecretsId>8ebb9eeb-02e2-49c6-ada9-e14634e4aeb7</UserSecretsId>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="9.0.3" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.19.6" />
<PackageReference Include="Scalar.AspNetCore" Version="2.1.1" />
<PackageReference Include="Swashbuckle.AspNetCore.ReDoc" Version="8.0.0" />
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="8.0.0" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\IssueManager.Core\IssueManager.Core.csproj" />
</ItemGroup>

</Project>
138 changes: 120 additions & 18 deletions src/IssueManager.Api/Program.cs
Original file line number Diff line number Diff line change
@@ -1,34 +1,136 @@
using IssueManager.Core.Exceptions;
using IssueManager.Core.Models.Interfaces;
using IssueManager.Core.RepositoryService;
using IssueManager.Core.RepositoryService.Interfaces;
using Microsoft.OpenApi.Models;
using Scalar.AspNetCore;

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenApi();

// Add services to the container.
builder.Services.AddSingleton<IRepositoryService, RepositoryService>();

var app = builder.Build();

// Configure the HTTP request pipeline.

app.UseHttpsRedirection();

var summaries = new[]
app.MapGet("/issues", async Task<IResult> (IRepositoryService repositoryService) =>
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
try
{
return TypedResults.Ok(await repositoryService.GetAllIssues());
}
catch (Exception exception)
{
Console.Error.WriteLine($"Error getting issues: {exception.Message}");
return TypedResults.Problem("An unexpected error occurred while getting issues.", statusCode: 500);
}
})
.WithName("GetIssues")
.WithOpenApi(x => new OpenApiOperation(x)
{
Summary = "Get all issues",
Description = "Returns all open issues.",
Tags = new List<OpenApiTag> { new() { Name = "All issues" } }
});

app.MapGet("/weatherforecast", () =>
app.MapGet("/issues/{id}", async Task<IResult> (int id, IRepositoryService repositoryService) =>
{
var forecast = Enumerable.Range(1, 5).Select(index =>
new WeatherForecast
(
DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
Random.Shared.Next(-20, 55),
summaries[Random.Shared.Next(summaries.Length)]
))
.ToArray();
return forecast;
try
{
return TypedResults.Ok(await repositoryService.GetIssueById(id));
}
catch (Exception exception)
{
Console.Error.WriteLine($"Error getting issue with ID {id}: {exception.Message}");
return TypedResults.Problem($"An unexpected error occurred while getting issue with ID: {id}.", statusCode: 500);
}
})
.WithName("GetIssueById")
.WithOpenApi(x => new OpenApiOperation(x)
{
Summary = "Get issue by ID",
Description = "Returns an issue with given ID.",
Tags = new List<OpenApiTag> { new() { Name = "Issue by ID" } }
});

app.Run();
app.MapDelete("/issues/{id}", async Task<IResult> (int id, IRepositoryService repositoryService) =>
{
try
{
await repositoryService.DeleteIssue(id);
}
catch (IssueNotFoundException)
{
return TypedResults.NotFound($"Issue with ID {id} not found.");
}
catch (Exception exception)
{
Console.Error.WriteLine($"Error deleting issue {id}: {exception.Message}");
return TypedResults.Problem("An unexpected error occurred while deleting the issue.", statusCode: 500);
}
return TypedResults.Ok($"Issue with ID {id} deleted successfully.");
})
.WithName("DeleteIssue").WithOpenApi(x => new OpenApiOperation(x)
{
Summary = "Delete issue by ID",
Description = "Deletes an issue with given ID.",
Tags = new List<OpenApiTag> { new() { Name = "Delete issue" } }
});

internal record WeatherForecast(DateOnly Date, int TemperatureC, string? Summary)
app.MapPost("/issues", async (IIssue issue, IRepositoryService repositoryService) =>
{
try
{
var id = await repositoryService.CreateIssue<int>(issue);
return Results.Created($"/issues/{id}", new { Id = id });
}
catch (Exception exception)
{
Console.Error.WriteLine($"Error creating issue: {exception.Message}");
return TypedResults.Problem("An unexpected error occurred while creating the issue.", statusCode: 500);
}
}
).WithName("CreateIssue").WithOpenApi(x => new OpenApiOperation(x)
{
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
Summary = "Create issue",
Description = "Creates an issue",
Tags = new List<OpenApiTag> { new() { Name = "Create issue" } }
});

app.MapPut("/issues/{id}", async (IIssue issue, IRepositoryService repositoryService) =>
{
try
{
var id = await repositoryService.UpdateIssue<int>(issue);

return Results.NoContent();
}
catch (IssueNotFoundException)
{
return TypedResults.NotFound($"Issue with ID not found.");
}
catch (Exception ex)
{
return Results.Problem(ex.Message);
}
}).WithName("UpdateIssue").WithOpenApi(x => new OpenApiOperation(x)
{
Summary = "Update issue",
Description = "Updates an issue",
Tags = new List<OpenApiTag> { new() { Name = "Update issue" } }
});

if (app.Environment.IsDevelopment())
{
app.MapOpenApi();
app.UseSwaggerUI(options =>
options.SwaggerEndpoint("/openapi/v1.json", "OpenAPI V1"));
app.UseReDoc(options =>
options.SpecUrl("/openapi/v1.json"));
app.MapScalarApiReference();

}
app.Run();
2 changes: 1 addition & 1 deletion src/IssueManager.Api/Properties/launchSettings.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "weatherforecast",
"launchUrl": "swagger",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
Expand Down
6 changes: 0 additions & 6 deletions src/IssueManager.Core/Class1.cs

This file was deleted.

4 changes: 4 additions & 0 deletions src/IssueManager.Core/Exceptions/IssueNotFoundException.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace IssueManager.Core.Exceptions;
public class IssueNotFoundException : Exception
{
}
2 changes: 1 addition & 1 deletion src/IssueManager.Core/IssueManager.Core.csproj
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
Expand Down
4 changes: 4 additions & 0 deletions src/IssueManager.Core/Models/Interfaces/IIssue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace IssueManager.Core.Models.Interfaces;
public interface IIssue
{
}
6 changes: 6 additions & 0 deletions src/IssueManager.Core/Models/Issue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
using IssueManager.Core.Models.Interfaces;

namespace IssueManager.Core.Models;
public class Issue : IIssue
{
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using IssueManager.Core.Models.Interfaces;

namespace IssueManager.Core.RepositoryService.Interfaces;

public interface IRepositoryService
{
public Task<List<IIssue>> GetAllIssues();
public Task<IIssue> GetIssueById<T>(T id);
public Task<T> UpdateIssue<T>(IIssue issue);
public Task<T> CreateIssue<T>(IIssue issue);
public Task DeleteIssue<T>(T id);
}
38 changes: 38 additions & 0 deletions src/IssueManager.Core/RepositoryService/RepositoryService.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using IssueManager.Core.Models.Interfaces;
using IssueManager.Core.RepositoryService.Interfaces;

namespace IssueManager.Core.RepositoryService;
public class RepositoryService : IRepositoryService
{
#pragma warning disable CS1998 // Async method lacks 'await' operators and will run synchronously
public async Task DeleteIssue<T>(T id)
{
throw new NotImplementedException();
}

public async Task<List<IIssue>> GetAllIssues()
{
throw new NotImplementedException();
}

public async Task<IIssue> GetIssueById<T>(T id)
{
throw new NotImplementedException();
}

public async Task<T> CreateIssue<T>(IIssue issue)
{
throw new NotImplementedException();
}

public async Task UpdateIssue(IIssue issue)
{
throw new NotImplementedException();
}

Task<T> IRepositoryService.UpdateIssue<T>(IIssue issue)
{
throw new NotImplementedException();
}
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>

Expand Down