Moongate.Hosting
0.20.1
Prefix Reserved
dotnet add package Moongate.Hosting --version 0.20.1
NuGet\Install-Package Moongate.Hosting -Version 0.20.1
<PackageReference Include="Moongate.Hosting" Version="0.20.1" />
<PackageVersion Include="Moongate.Hosting" Version="0.20.1" />
<PackageReference Include="Moongate.Hosting" />
paket add Moongate.Hosting --version 0.20.1
#r "nuget: Moongate.Hosting, 0.20.1"
#:package Moongate.Hosting@0.20.1
#addin nuget:?package=Moongate.Hosting&version=0.20.1
#tool nuget:?package=Moongate.Hosting&version=0.20.1
Moongate.Hosting
The generic host layer of Moongate: startup services, an event bus, a plugin registry, TOML configuration sections, and the contracts of the game loop, timers, diagnostics, and shutdown. It depends only on Moongate.Core, so an application can use it without the Ultima Online stack.
Installation
Requires .NET 10. Use the package version available in your configured NuGet feed.
dotnet add package Moongate.Hosting
Features
IMoongateServiceandIMoongateStartupService, the contracts of a service and of one that starts and stops with the host.- An event bus integrated with DryIoc, and the started, stopping and stopped lifecycle events.
- A plugin contract (
IMoongatePlugin), its metadata and dependencies, and the registry that orders plugins and calls theirRegister; the host that runs them lives inMoongate.Server. - TOML configuration sections (
IConfigSection) read from a document and registered in the container. - Contracts and options for the game loop, timers, diagnostics and metric providers, and the shutdown request.
Example
A small application built on Moongate.Hosting alone: a configuration file shared with plugins, an event bus, a service that
starts with the host, and a plugin that registers its own configuration section. The example starts the service and
publishes the lifecycle event by hand; it does not run a host or a game loop.
using DryIoc;
using Moongate.Server.Core.Data.Config;
using Moongate.Server.Core.Data.Events;
using Moongate.Server.Core.Data.Plugins;
using Moongate.Server.Core.Extensions;
using Moongate.Server.Core.Interfaces.Events;
using Moongate.Server.Core.Interfaces.Plugins;
using Moongate.Server.Core.Interfaces.Services;
using Tomlyn;
using Tomlyn.Model;
using var container = new Container();
// The parsed configuration file, shared with the plugins that own a section of it.
var toml = "[greeting]\ntext = \"Hello\"\n";
container.RegisterInstance(new ServerConfigDocument("moongate.toml", TomlSerializer.Deserialize<TomlTable>(toml)!, []));
container.RegisterMoongateEventBus();
// A service the host starts and stops, and a plugin that registers its configuration section.
container.AddMoongateService<IGreeter, Greeter>(priority: 5);
container.RegisterMoongatePlugin(new GreetingPlugin());
var bus = container.Resolve<IMoongateEventBus>();
using var subscription = bus.Subscribe<MoongateStartedEvent>((_, cancellationToken) =>
{
Console.WriteLine("Started");
return Task.CompletedTask;
});
// A host starts each registered service and then announces that it has started.
await ((IMoongateStartupService)container.Resolve<IGreeter>()).StartAsync();
await bus.PublishAsync(new MoongateStartedEvent());
public interface IGreeter : IMoongateService;
public sealed class Greeter(GreetingConfig config) : IGreeter, IMoongateStartupService
{
public Task StartAsync()
{
Console.WriteLine(config.Text);
return Task.CompletedTask;
}
public Task StopAsync() => Task.CompletedTask;
}
public sealed class GreetingConfig
{
public string Text { get; set; } = "default";
}
public sealed class GreetingPlugin : IMoongatePlugin
{
public MoongatePluginData Metadata { get; } = new("greeting", "Greeting", new(1, 0, 0));
public void Register(Container container) => container.AddConfig<GreetingConfig>("greeting");
}
SubscribeAll registers a handler invoked for every published event, independent of
type, dispatched after that event's own typed subscribers in subscription order.
Each catch-all subscription is independent and returns its own disposable token,
exactly like Subscribe<TEvent>; disposing one never affects another.
Namespaces
The types keep the namespaces they had in Moongate.Server.Core (Moongate.Server.Core.Interfaces.Services,
Moongate.Server.Core.Extensions, and so on), so source written against that package keeps compiling. Binaries built against an earlier Moongate.Server.Core
must be rebuilt, because the types now live in another assembly (and plugins already need the exact host version).
They may be renamed in a later release.
Dependencies and scope
This package depends on Moongate.Core; DryIoc, Serilog and Tomlyn come through it. It has no reference to the network,
packet, persistence or Ultima libraries.
The implementations of the loop, timers and diagnostics, and the executable host, are provided by Moongate.Server,
which is not distributed as a library package. Referencing this package does not start a host, timers, or a game loop.
License and source
Licensed under AGPL-3.0-or-later. See the source repository and license.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- Moongate.Core (>= 0.20.1)
NuGet packages (1)
Showing the top 1 NuGet packages that depend on Moongate.Hosting:
| Package | Downloads |
|---|---|
|
Moongate.Server.Core
Plugin-facing server contracts, events, registries, and dependency injection extensions for Moongate. |
GitHub repositories
This package is not used by any popular GitHub repositories.