Skip to content

MVC-free framework: IContextProvider, IArkAttachment, Application/Hosting split, NodaTime protobuf#742

Draft
AndreaCuneo with Copilot wants to merge 7 commits into
masterfrom
copilot/create-architectural-report-docs
Draft

MVC-free framework: IContextProvider, IArkAttachment, Application/Hosting split, NodaTime protobuf#742
AndreaCuneo with Copilot wants to merge 7 commits into
masterfrom
copilot/create-architectural-report-docs

Conversation

Copilot AI commented Jul 2, 2026

Copy link
Copy Markdown
Contributor

Incorporates four prerequisite changes into the source-generated, MVC-free web-services work before continuing the remaining transport epics: adopt the existing identity/attachment abstractions, restructure the sample to match the ReferenceProject layering, and add NodaTime-over-protobuf support.

Identity: IUserContextIContextProvider<ClaimsPrincipal>

  • Removed the bespoke IUserContext; handlers now consume the existing IContextProvider<ClaimsPrincipal> (Ex.GetUserId()).
  • HostUserContextProvider reuses the shipped implementations: HttpContext.User (as AspNetCoreUserContextProvider does) for the HTTP path, RebusPrincipalContextWithFallbackProvider for the bus path, with propagation via AutomaticallyFlowUserContext / UserFlowStep.
  • Deliberately avoids referencing the MVC-heavy Ark.Tools.AspNetCore from the MVC-free sample.

Attachments: generic IProxyStreamIArkAttachment

  • New non-generic IArkAttachment (Name, ContentType, OpenRead()) + ArkAttachment. Hosting maps IFormFileArkAttachment at a hand-written multipart endpoint; the pure handler streams it.

Sample restructure (mirrors ReferenceProject)

  • …Sample.Application — transport-agnostic contracts/handlers/store/decorator.
  • …Sample.WebInterface — composition root + startup; this is where selected requests/queries are exposed as endpoints and transports (user context, Rebus) are wired.
  • Removed the old combined …Sample.Api.
  • Generator now discovers [ArkEndpoint] cross-assembly, so hosting emits endpoints for contracts declared in Application. (ponytail: scans per-compilation; upgrade path = per-metadata-reference caching.)

NodaTime over protobuf (Ark.Tools.Nodatime.Protobuf)

protobuf-net surrogates registered via RuntimeTypeModel.AddNodaTimeSurrogates():

Type Encoding
OffsetDateTime local date-time + offset seconds (offset preserved)
LocalDate year/month/day (date only)
LocalDateTime date + nanosecond-of-day (zoneless)
Period ISO-8601 round-trip string
RuntimeTypeModel.Default.AddNodaTimeSurrogates();

Docs

  • design.md, research.md, tasks.md, implementation-plan.md, sample README.md updated for the new abstractions, the Application/Hosting split, and the NodaTime capability; T5.1, T6.2 and a new T4.4 marked accordingly.

Notes for reviewers

  • Microsoft.CodeAnalysis.CSharp was centralized earlier on this branch; 6 transitive packages.lock.json files are regenerated (locked-mode restore).
  • protobuf-net is the only added dependency (already sanctioned by the task).

Copilot AI and others added 4 commits July 1, 2026 20:00
Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
…ple into build

Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
…se IContextProvider and IArkAttachment

Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
… layering, NodaTime protobuf; refresh lockfiles

Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>

@AndreaCuneo AndreaCuneo left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot review all comments as if were for you.

apply changes to design, tasks, and current implementation. Then proceed with next step.

Comment thread docs/mvc-free-framework/design.md Outdated
```

Routing/metadata is expressed with attributes on the request type (e.g.
`[ArkEndpoint("POST", "/api/v1/orders")]`, `[ServiceGroup("Orders")]`,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use Http Endpoint and Grpc Method. make the transport declaration explicit.

Comment thread docs/mvc-free-framework/design.md Outdated
2. **Semantic analysis** — resolves the symbol, response type, routing
attributes and parameter sources against the compilation's semantic model for
type safety.
3. **Transport emission** — emits partial extension methods that wire the pure

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

make this "opt-in" so that in case the Framework is "limited" for a single Request/Query, the developer can manually implement the grpc method within the Service partial or the Map or the MessageHandler

Comment thread docs/mvc-free-framework/design.md Outdated
CreateOrderRequest request, HttpContext ctx, CancellationToken ctk) =>
{
var container = ctx.RequestServices.GetRequiredService<SimpleInjector.Container>();
await using var scope = AsyncScopedLifestyle.BeginScope(container);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

scope is handled by simpleinjector integration in the pipeline. the scope is the entire request. other middlewares depends on the scope.

Comment thread docs/mvc-free-framework/design.md Outdated
`IHandleMessages<CreateOrderRequest>` whose `Handle` opens the SimpleInjector
scope (seeded from `MessageContext.Current.Headers`) and invokes the pure
handler. The message is the unit of work / transaction boundary via the Rebus
unit-of-work integration.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do not use Rebus.UnitOfWork
Rebus pipeline already has support for SimpleInjector scope

…e DI scope

Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>

Copilot AI commented Jul 2, 2026

Copy link
Copy Markdown
Contributor Author

@copilot review all comments as if were for you.

apply changes to design, tasks, and current implementation. Then proceed with next step.

Applied all four review points to design, tasks and the sample implementation in e8f6346:

  • Explicit transports[ArkEndpoint] replaced by explicit, per-transport [HttpEndpoint], [RebusMessage] and [GrpcMethod].
  • Opt-in emission — the generator emits a transport only when its attribute is present; omitting it lets you hand-write the gRPC method (service partial), the Map* call, or the IHandleMessages<> directly.
  • Request-wide scope — the generated Minimal API endpoint no longer opens its own scope; the SimpleInjector scope spans the whole request via the hosting pipeline, so other middlewares share it.
  • No Rebus.UnitOfWork — the sample now relies on the Rebus pipeline's per-message SimpleInjector scope (RebusScopeDecorator<>).

Sample builds clean and all 5 self-tests pass. Next step is the code-first gRPC transport (T4.1), which is now opt-in-ready but requires the protobuf-net.Grpc.AspNetCore / Grpc.Net.Client dependencies — flagging since new dependencies need approval.

…versioning

Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Comment on lines +277 to +285
foreach (var segment in template.Split('/'))
{
if (segment.Length >= 2
&& (segment[0] == 'v' || segment[0] == 'V')
&& segment.Skip(1).All(char.IsDigit))
{
return "v" + segment.Substring(1);
}
}
@AndreaCuneo

Copy link
Copy Markdown
Contributor

@copilot continue working on the next steps. review all documents before proceeding.

Agent-Logs-Url: https://github.com/ARKlab/Ark.Tools/sessions/6797d97c-25a8-40fa-89cf-174bbbc785cb

Co-authored-by: AndreaCuneo <5227688+AndreaCuneo@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants