Skip to content

Commit 1f07c1a

Browse files
committed
Implement core services for Article, Auth, Profile, and Tag management
- Added ArticleService for handling article-related operations including fetching, creating, updating, and deleting articles, as well as managing comments and favorites. - Introduced AuthService for user authentication, registration, and session management. - Created ProfileService to manage user profiles, including fetching and following/unfollowing users. - Developed TagService to retrieve available tags for articles. - Established a new ASP.NET Core Web API project structure with appropriate configurations and launch settings. - Implemented in-memory data storage for users, articles, and comments to facilitate API operations. - Added HTTP request/response models for user and article interactions. - Configured logging and environment settings for development.
1 parent 048ae12 commit 1f07c1a

35 files changed

+3773
-122
lines changed

.vscode/launch.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,12 @@
44
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
55
"version": "0.2.0",
66
"configurations": [
7+
{
8+
"name": "C#: Abies. Debug",
9+
"type": "dotnet",
10+
"request": "launch",
11+
"projectPath": "${workspaceFolder}/Abies.Conduit/Abies.Conduit.csproj"
12+
},
713
{
814
"type": "msedge",
915
"request": "launch",

Abies.Conduit/Abies.Conduit.csproj

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
11
<Project Sdk="Microsoft.NET.Sdk.WebAssembly">
22
<PropertyGroup>
33
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
4-
<PublishTrimmed>false</PublishTrimmed>
4+
<PublishTrimmed>false</PublishTrimmed>
55
<TargetFramework>net9.0</TargetFramework>
6+
<!-- Disable auto-generated assembly attributes to avoid duplicates -->
7+
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
8+
<!-- Prevent duplicate TargetFrameworkAttribute -->
9+
<GenerateTargetFrameworkAttribute>false</GenerateTargetFrameworkAttribute>
610
</PropertyGroup>
711
<ItemGroup>
812
<ProjectReference Include="..\Abies\Abies.csproj" />

Abies.Conduit/ApiCommandHandler.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using System;
2+
using System.Runtime.CompilerServices;
3+
using System.Runtime.InteropServices.JavaScript;
4+
using System.Threading.Tasks;
5+
6+
namespace Abies;
7+
8+
// Make this accessible to the Abies.Types HandleCommand method
9+
public abstract class ApiCommand : Abies.Command
10+
{
11+
public abstract Task<Abies.Message> ExecuteAsync();
12+
}
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
using System;
2+
using System.Collections.Generic;
3+
using System.Threading.Tasks;
4+
using Abies;
5+
6+
namespace Abies.Conduit
7+
{
8+
/// <summary>
9+
/// Base interface for API commands
10+
/// </summary>
11+
public interface IApiCommand
12+
{
13+
Task ExecuteAsync();
14+
}
15+
16+
/// <summary>
17+
/// Represents a command that can be executed to interact with the API without expecting a specific result.
18+
/// </summary>
19+
public abstract class ApiCommand : Command, IApiCommand
20+
{
21+
/// <summary>
22+
/// Executes the API command asynchronously.
23+
/// </summary>
24+
/// <returns>A task that completes when the command has been executed.</returns>
25+
public abstract Task ExecuteAsync();
26+
}
27+
28+
/// <summary>
29+
/// Represents a command that can be executed to interact with the API and returns a specific result.
30+
/// </summary>
31+
/// <typeparam name="TResult">The type of message returned by the command execution.</typeparam>
32+
public abstract class ApiCommand<TResult> : Command, IApiCommand where TResult : Message
33+
{
34+
/// <summary>
35+
/// Executes the API command asynchronously.
36+
/// </summary>
37+
/// <returns>A task that resolves to the message result.</returns>
38+
public abstract Task<TResult> ExecuteAsync();
39+
40+
/// <summary>
41+
/// Implementation of the IApiCommand interface.
42+
/// </summary>
43+
async Task IApiCommand.ExecuteAsync()
44+
{
45+
await ExecuteAsync();
46+
}
47+
}
48+
49+
/// <summary>
50+
/// Static extension methods for handling API commands.
51+
/// </summary>
52+
public static class ApiCommandExtensions
53+
{
54+
/// <summary>
55+
/// Handles API commands during the update cycle.
56+
/// </summary>
57+
/// <param name="commands">The collection of commands to process.</param>
58+
/// <returns>The same commands for proper chaining with the Abies framework.</returns>
59+
public static IEnumerable<Command> HandleApiCommands(this IEnumerable<Command> commands)
60+
{
61+
foreach (var command in commands)
62+
{
63+
if (command is IApiCommand apiCommand)
64+
{
65+
Task.Run(async () =>
66+
{
67+
try
68+
{
69+
await apiCommand.ExecuteAsync();
70+
}
71+
catch (Exception)
72+
{
73+
// Exception handling is done in the command itself
74+
}
75+
});
76+
}
77+
}
78+
79+
// Return the original commands so they can be processed by the Abies framework
80+
return commands;
81+
}
82+
}
83+
84+
/// <summary>
85+
/// Runtime helper to support dispatching messages from API commands.
86+
/// </summary>
87+
public static class RuntimeDispatcher
88+
{
89+
private static readonly System.Reflection.MethodInfo? _dispatchMethod;
90+
private static readonly object? _program;
91+
92+
static RuntimeDispatcher()
93+
{
94+
try
95+
{
96+
var programField = typeof(Runtime).GetField("_program",
97+
System.Reflection.BindingFlags.NonPublic |
98+
System.Reflection.BindingFlags.Static);
99+
100+
_program = programField?.GetValue(null);
101+
102+
if (_program != null)
103+
{
104+
// Get the Dispatch method that takes a Message parameter
105+
_dispatchMethod = _program.GetType().GetMethod("Dispatch",
106+
new[] { typeof(Message) });
107+
}
108+
}
109+
catch (Exception)
110+
{
111+
// Silently fail
112+
}
113+
}
114+
115+
/// <summary>
116+
/// Dispatches a message to the Abies runtime.
117+
/// </summary>
118+
/// <param name="message">The message to dispatch.</param>
119+
public static async Task Dispatch(Message message)
120+
{
121+
if (_dispatchMethod != null && _program != null)
122+
{
123+
var task = (Task)_dispatchMethod.Invoke(_program, new object[] { message })!;
124+
if (task != null)
125+
{
126+
await task;
127+
}
128+
}
129+
else
130+
{
131+
Console.WriteLine("Cannot dispatch message: Runtime not properly initialized");
132+
}
133+
}
134+
}
135+
}

0 commit comments

Comments
 (0)