An open API service indexing awesome lists of open source software.

https://github.com/salihcantekin/space

High-performance, source-generator powered mediator and messaging framework for .NET.
https://github.com/salihcantekin/space

dotnet mediator mediatr messaging sourcegenerator space

Last synced: 9 months ago
JSON representation

High-performance, source-generator powered mediator and messaging framework for .NET.

Awesome Lists containing this project

README

          

# Space

High-performance, source-generator powered mediator / messaging framework for .NET. Eliminates runtime reflection, minimizes boilerplate, and provides an extensible module + pipeline model for cross-cutting concerns (e.g., caching, auditing).

---
## Status & Packages

| CI | Branch | Status |
|----|--------|--------|
| Prod (Stable Publish) | `master` | ![Prod CI](https://github.com/salihcantekin/Space/actions/workflows/prod-ci.yml/badge.svg) |
| Dev (Preview Publish) | `dev` | ![Dev CI](https://github.com/salihcantekin/Space/actions/workflows/dev-ci.yml/badge.svg) |
| Validation (PR / Feature) | PRs -> `dev` / `master` | ![Validation Build](https://github.com/salihcantekin/Space/actions/workflows/validation-build.yml/badge.svg) |

### NuGet Packages

| Package | Stable | Preview | Downloads | Description |
|---------|--------|---------|-----------|-------------|
| Space.Abstraction | ![NuGet](https://img.shields.io/nuget/v/Space.Abstraction.svg) | ![NuGet (pre)](https://img.shields.io/nuget/vpre/Space.Abstraction.svg) | ![Downloads](https://img.shields.io/nuget/dt/Space.Abstraction.svg) | Core abstractions: attributes, contexts, contracts |
| Space.DependencyInjection | ![NuGet](https://img.shields.io/nuget/v/Space.DependencyInjection.svg) | ![NuGet (pre)](https://img.shields.io/nuget/vpre/Space.DependencyInjection.svg) | ![Downloads](https://img.shields.io/nuget/dt/Space.DependencyInjection.svg) | DI extensions + source generator bootstrap |
| Space.Modules.InMemoryCache | ![NuGet](https://img.shields.io/nuget/v/Space.Modules.InMemoryCache.svg) | ![NuGet (pre)](https://img.shields.io/nuget/vpre/Space.Modules.InMemoryCache.svg) | ![Downloads](https://img.shields.io/nuget/dt/Space.Modules.InMemoryCache.svg) | In-memory caching module + attribute integration |

### Install (Minimal)
```bash
dotnet add package Space.Abstraction
dotnet add package Space.DependencyInjection
```
Optional module:
```bash
dotnet add package Space.Modules.InMemoryCache
```

---
## Quick Start
```csharp
using Microsoft.Extensions.DependencyInjection;

var services = new ServiceCollection();
services.AddSpace(opt =>
{
opt.NotificationDispatchType = NotificationDispatchType.Parallel; // or Sequential
});
services.AddSpaceInMemoryCache(); // if caching module needed

var provider = services.BuildServiceProvider();
var space = provider.GetRequiredService();

public sealed record UserLoginRequest(string UserName);
/*
The response type can be defined using IRequest.
*/
public sealed record UserLoginRequest(string UserName) : IRequest
public sealed record UserLoginResponse(bool Success);

public class UserHandlers
{
[Handle]
public ValueTask Login(HandlerContext ctx)
=> ValueTask.FromResult(new UserLoginResponse(true));
}

/*
The same functionality can be implemented using the IHandler interface.
The primary difference from the attribute-based approach is that the method name will be explicitly defined in the interface implementation.
*/

public class UserHandlers : IHandler
{
public ValueTask Handle (UserLoginRequest request, CancellationToken cancellationToken)
=> ValueTask.FromResult(new UserLoginResponse (true));
}

var response = await space.Send(new UserLoginRequest("demo"));
/*
A more efficient solution can be achieved in the Send method by utilizing both the request and response types.
*/
var response = await space.Send(new UserLoginRequest("demo"))
```

### Named Handlers
```csharp
public class PricingHandlers
{
[Handle(Name = "Default")] public ValueTask GetDefault(HandlerContext ctx) => ...;
[Handle(Name = "Discounted")] public ValueTask GetDiscounted(HandlerContext ctx) => ...;
}
var discounted = await space.Send(new PriceQuery(...), handlerName: "Discounted");
```

### Pipelines
```csharp
public class LoggingPipeline
{
[Pipeline(Order = 100)]
public async ValueTask Log(PipelineContext ctx)
{
// pre-execution
var result = await ctx.Next(ctx);
// post-execution
return result;
}
}
```

### Notifications
```csharp
public sealed record UserLoggedIn(string UserName);
public class LoginNotifications
{
[Notification]
public ValueTask Log(NotificationContext ctx) => ValueTask.CompletedTask;
}
await space.Publish(new UserLoggedIn("demo"));
```

### Caching Module Example
```csharp
public class UserQueries
{
[Handle]
[CacheModule(DurationSeconds = 60)]
public ValueTask GetUser(HandlerContext ctx) => ...;
}
```
`[CacheModule]` (from Space.Modules.InMemoryCache) inserts caching logic before user pipelines.

---
## Key Features
- Zero runtime reflection for discovery (Roslyn source generator)
- Minimal boilerplate: annotate methods directly with `[Handle]`, `[Pipeline]`, `[Notification]`
- Named handlers (multiple strategies for same request/response)
- Orderable pipelines + early system module execution
- Extensible module model (e.g., cache) before user pipelines
- High-performance async signatures (`ValueTask`)
- Parallel or sequential notification dispatch
- Multi-targeting (netstandard2.0 + modern .NET)

---
## Performance Philosophy
Space front-loads cost at build time to reduce runtime overhead:
- Compile-time metadata (registrations, maps)
- No reflection-based runtime scanning
- Low allocation pathways (current & planned pooling)

Benchmarks (planned) will compare against other mediator libraries.

---
## Documentation
Primary docs in `docs/`:

| Topic | Link |
|-------|------|
| Project Overview | [ProjectDoc.en.md](docs/ProjectDoc.en.md) |
| Handlers | [Handlers](docs/Handlers.md) |
| Pipelines | [Pipelines](docs/Pipelines.md) |
| Notifications | [Notifications](docs/Notifications.md) |
| Modules | [Modules](docs/Modules.md) |
| Developer Recommendations | [DeveloperRecommendations](docs/DeveloperRecommendations.md) |
| Known Issues | [KnownIssues](docs/KnownIssues.md) |
| Planned Improvements | [PlannedImprovements](docs/PlannedImprovements.md) |

Per-package:
- [Space.Abstraction](src/Space.Abstraction/README.md)
- [Space.DependencyInjection](src/Space.DependencyInjection/README.md)

---
## Roadmap & Issues
See GitHub Issues for:
- Planned improvements (attribute parameters, global defaults, Options pattern)
- Known issues (initial Lazy `ISpace` null, module scoping on named handlers)

Contributions welcome via issues & PRs.

---
## Versioning & Releases
- `master`: tagged semantic versions (`vX.Y.Z`) ? stable NuGet
- `dev`: continuous preview (`X.Y.(Patch+1)-preview.`)
- Feature branches: validation build only

---
## License
MIT.

---
## Disclaimer
APIs may evolve while early preview features stabilize. Track releases for changes.

---
# Space

Space is a high-performance, source-generator powered mediator/messaging framework for .NET.

- Docs: see the `docs/` folder
- Contribution guide for modules: see [docs/Contribution.md](docs/Contribution.md)

## Quick links
- Handlers: docs/Handlers.md
- Pipelines: docs/Pipelines.md
- Notifications: docs/Notifications.md
- Known Issues: docs/KnownIssues.md
- Developer Recommendations: docs/DeveloperRecommendations.md

## Build
See `.github/copilot-instructions.md` for environment and common commands.