Initial API setup and basic program functioning

This commit is contained in:
2026-03-24 12:29:07 +10:30
parent e5fcaad365
commit f26ff6e04a
17 changed files with 279 additions and 0 deletions
+18
View File
@@ -0,0 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<Nullable>enable</Nullable>
<ImplicitUsings>enable</ImplicitUsings>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.0.5" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Emergence.models\Emergence.models.csproj" />
<ProjectReference Include="..\Emergence.services\Emergence.services.csproj" />
</ItemGroup>
</Project>
+11
View File
@@ -0,0 +1,11 @@
@Emergence.api_HostAddress = http://localhost:5235
GET {{Emergence.api_HostAddress}}/users/
Accept: application/json
###
GET {{Emergence.api_HostAddress}}/users/2
Accept: application/json
###
GET {{Emergence.api_HostAddress}}/openapi/emergence.yaml
Accept: application/json
###
+30
View File
@@ -0,0 +1,30 @@
using Emergence.api.Interfaces;
using Emergence.models;
using Emergence.services.Interface;
using Microsoft.AspNetCore.Http.HttpResults;
namespace Emergence.api.Endpoints;
public class UserEndpoints : IEndpoint
{
private readonly IUserService _userService;
public UserEndpoints(IUserService userService)
{
_userService = userService;
}
public void MapEndPoint(IEndpointRouteBuilder app)
{
var endpoints = app.MapGroup("/users")
.WithTags("User Items");
endpoints.MapGet("/", GetAll).Produces<List<UserModel>>(StatusCodes.Status200OK).Produces(StatusCodes.Status404NotFound).WithName("Get All Users");
endpoints.MapGet("/{id}", GetById).Produces<string>(StatusCodes.Status200OK).Produces(StatusCodes.Status404NotFound).WithName("Get User By Id");
}
public async Task<Results<Ok<List<UserModel>>, NotFound>> GetAll() =>
await _userService.GetAllAsync() is List<UserModel> result ? TypedResults.Ok(result) : TypedResults.NotFound();
public async Task<Results<Ok<UserModel>, NotFound>> GetById(int id) =>
await _userService.GetByIdAsync(id) is UserModel result ? TypedResults.Ok(result) : TypedResults.NotFound();
}
@@ -0,0 +1,39 @@
using Emergence.api.Interfaces;
using Microsoft.Extensions.DependencyInjection.Extensions;
using System.Reflection;
namespace Emergence.api.Extensions;
public static class EndpointExtension
{
public static IServiceCollection AddEndpoints(this IServiceCollection services, Assembly assembly)
{
// Find all classes that implement IEndpoint and register them for DI
ServiceDescriptor[] serviceDescriptors = assembly
.DefinedTypes
.Where(type => type is { IsAbstract: false, IsInterface: false } &&
type.IsAssignableTo(typeof(IEndpoint)))
.Select(type => ServiceDescriptor.Transient(typeof(IEndpoint), type))
.ToArray();
services.TryAddEnumerable(serviceDescriptors);
return services;
}
public static IApplicationBuilder MapEndpoints(this WebApplication app, RouteGroupBuilder? routeGroupBuilder = null)
{
IEnumerable<IEndpoint> endpoints = app.Services
.GetRequiredService<IEnumerable<IEndpoint>>();
IEndpointRouteBuilder builder =
routeGroupBuilder is null ? app : routeGroupBuilder;
foreach (IEndpoint endpoint in endpoints)
{
endpoint.MapEndPoint(builder);
}
return app;
}
}
+7
View File
@@ -0,0 +1,7 @@
namespace Emergence.api.Interfaces
{
public interface IEndpoint
{
void MapEndPoint(IEndpointRouteBuilder app);
}
}
+22
View File
@@ -0,0 +1,22 @@
using Emergence.api.Extensions;
using Emergence.services.Extensions;
var builder = WebApplication.CreateBuilder(args);
// Add services to the container.
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();
builder.Services.AddServices();
builder.Services.AddEndpoints(typeof(Program).Assembly);
var app = builder.Build();
app.UseHttpsRedirection();
app.MapEndpoints();
// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
app.MapOpenApi("/openapi/emergence.yaml");
}
app.Run();
@@ -0,0 +1,23 @@
{
"$schema": "https://json.schemastore.org/launchsettings.json",
"profiles": {
"http": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "http://localhost:5235",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"https": {
"commandName": "Project",
"dotnetRunMessages": true,
"launchBrowser": false,
"applicationUrl": "https://localhost:7228;http://localhost:5235",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
@@ -0,0 +1,8 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
}
}
+9
View File
@@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft.AspNetCore": "Warning"
}
},
"AllowedHosts": "*"
}
+9
View File
@@ -0,0 +1,9 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
</Project>
+13
View File
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Emergence.models
{
public class UserModel
{
public int Id { get; set; }
public string Username { get; set; }
public string Email { get; set; }
}
}
@@ -0,0 +1,17 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.DependencyInjection.Abstractions" Version="10.0.5" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Emergence.models\Emergence.models.csproj" />
</ItemGroup>
</Project>
@@ -0,0 +1,19 @@
using Emergence.services.Interface;
using Emergence.services.Services;
using Microsoft.Extensions.DependencyInjection;
using System;
using System.Collections.Generic;
using System.Text;
namespace Emergence.services.Extensions
{
public static class ServiceBuilderExtension
{
public static IServiceCollection AddServices(this IServiceCollection services)
{
services = services.AddTransient<IUserService, UserService>();
return services;
}
}
}
+12
View File
@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Emergence.services.Interface
{
public interface IService<T> where T : class
{
public Task<IList<T>> GetAllAsync();
public Task<T> GetByIdAsync(int id);
}
}
@@ -0,0 +1,11 @@
using Emergence.models;
using System;
using System.Collections.Generic;
using System.Text;
namespace Emergence.services.Interface
{
public interface IUserService : IService<UserModel>
{
}
}
@@ -0,0 +1,26 @@
using Emergence.models;
using Emergence.services.Interface;
namespace Emergence.services.Services;
public class UserService : IUserService
{
private List<UserModel> testList = [
new UserModel {Id = 1, Username = "chris", Email ="chris@fjp.com.au" },
new UserModel {Id = 2, Username = "kim", Email ="kim@fjp.com.au" },
new UserModel {Id = 3, Username = "amanda", Email ="amanda@fjp.com.au" },
new UserModel {Id = 4, Username = "reception", Email ="reception@fjp.com.au" },
];
public async Task<IList<UserModel>> GetAllAsync()
{
return testList;
}
public async Task<UserModel> GetByIdAsync(int id)
{
#pragma warning disable CS8603 // Possible null reference return.
return testList.FirstOrDefault(f => f.Id == id);
#pragma warning restore CS8603 // Possible null reference return.
}
}
+5
View File
@@ -0,0 +1,5 @@
<Solution>
<Project Path="Emergence.api/Emergence.api.csproj" />
<Project Path="Emergence.models/Emergence.models.csproj" Id="289779a8-43b3-44ec-994b-2ac4fbc29327" />
<Project Path="Emergence.services/Emergence.services.csproj" Id="4a98db16-1ee8-486a-bcb9-5c9fa705a616" />
</Solution>