> ## Content Index
> Fetch the complete content index at: https://blogs.remobjects.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# New Hosting Packages for Remoting SDK
- URL: https://blogs.remobjects.com/2021/05/27/new-hosting-packages-for-remoting-sdk/
- Published: 2021-05-27T15:57:02.000Z
- Updated: 2021-05-27T15:58:56.000Z
- Description: Remoting SDK for .NET adds support for Microsoft.Extensions.Hosting and Topshelf.
- Author: Anton Kasyanov
- Tags: #Import 2026-08-17 20:17

`ApplicationServer` boilerplate once was a rather valuable addition to [Remoting SDK for .NET](https://www.remotingsdk.com/?ref=blogs.remobjects.com). The entire server application infrastructure became available literally via a single line of code:

```c#
public static void Main(string[] args)
{
   new ApplicationServer("Server App Name").Run(args);
}

```

Out-of-the-box support for command-line, GUI or Windows Service/Daemon run modes, customizable server parameters, transparent access to TLS support and other features allowed developers to focus on the business logic code rather on the boring infrastructure implementation details.

As time passed, .NET Core and .NET 5 brought us developed infrastructure like de-facto built-in Dependency Injection support and new program initialization abstractions. So inevitable at some point `ApplicationServer`\-based code started to look slightly obsolete. Even the recent addition of Dependency Injection containers ([see here for details](https://blogs.remobjects.com/2020/11/03/dependency-injection-in-remoting-sdk-for-net-i/)) support did not help `ApplicationServer` to start feeling native to the new world of .NET Core and .NET 5\. To add insult to injury, the internal `ApplicationServer` infrastructure did not play well with the new `BackgroundService` class provided by .NET Core / .NET 5.

## The Solution

Still every challenge is an opportunity to evolve. So here it is - a support for 2 different application hosting packages: [Microsoft.Extensions.Hosting](http://microsoft.extensions.hosting/?ref=blogs.remobjects.com) and Topshelf.

## Microsoft.Extensions.Hosting Support

Support for the `Microsoft.Extensions.Hosting.*` packages family is provided via the `RemObjects.SDK.Extensions.Hosting.Microsoft` NuGet package.

The minimal server application startup code that uses this package looks like

```c#
static class Program
{
	public static void Main(string[] args)
	{
		var host = CreateHostBuilder(args)
			.Build();

		host.Run();
	}

	public static IHostBuilder CreateHostBuilder(string[] args)
	{
		return Host.CreateDefaultBuilder(args)
				.ConfigureServices((hostContext, services) =>
				{
				})
				.UseApplicationServer(configuration =>
				{
				})
				.UseNetworkServer(server =>
				{
				})
				.UseConsoleLifetime();
	}
}
```

The callback method defined in the `ConfigureServices` method call is the place where the dependencies used in the application should be defined.

Then two application server-related methods are called.

The `UseApplicationServer` method call is the place where the main server properties like its name, RODL namespace and self-signed certificate properties (if any) are defined and the main server infrastructure is initialized. This method call is required to make the application work as a Remoting SDK or Data Abstract server. If no custom values are provided then both application name and its RODL namespace will be set to `ApplicationServer`.

Then the `UseNetworkServer` method should be called. This method sets up the network server and allows to fine-tune its options like the port or server channel type used, or even to define custom network server implementation (see below).

These two method calls initialize the server infrastructure similar to the one provided earlier by the `ApplicationServer` class.

What's more important is that new methods allow to inject Remoting SDK application server lifecycle as a native part of the .NET Core / .NET 5 application lifecycle. For example this allows to use Dependency Injection container provided by Microsoft, as well as use packages that allow the app to run as Windows Service or a Systemd daemon (`Microsoft.Extensions.Hosting.WindowsServices` and `Microsoft.Extensions.Hosting.Systemd` accordingly).

For example to turn the application into a Windows Service one would need to reference the `Microsoft.Extensions.Hosting.WindowsServices` package and to replace the `UseConsoleLifetime` method call with the `UseWindowsService` method call.

Once the application is built it, needs to be installed as a Windows Service. Unfortunately the `Microsoft.Extensions.Hosting.WindowsServices` package does not provide its own installer so the standard Windows Service installer should be used:

```
sc create [Service Name] BinPath=[full path to the server app exe file]

```

Several other commands are available that allow to start, stop or delete the Windows Service:

```
sc start [Service Name]
sc stop [Service Name]
sc delete [Service Name]
```

## Topshelf Support

Support for the [Topshelf](http://topshelf-project.com/?ref=blogs.remobjects.com) framework is provided via the `RemObjects.SDK.Extensions.Hosting.Topshelf` package.

Topshelf describe itself as such:

> Topshelf is a framework for hosting services written using the .NET framework. The creation of services is simplified, allowing developers to create a simple console application that can be installed as a service using Topshelf

More info on this framework can be found on its [documentation site](https://topshelf.readthedocs.io/en/latest/overview/index.html?ref=blogs.remobjects.com).

The minimal application startup code that uses this package looks like this:

```c#
static void Main(string[] args)
{
	HostFactory.Run(host =>
	{
		host.ConfigureServices(services =>
		{
		});
		host.UseApplicationServer(configuration =>
		{
		});
		host.UseNetworkServer(server =>
		{
		});

		host.UseHostedService();
	});
}
```

The `ConfigureServices`, `UseApplicationServer` and `UseNetworkServer` methods have exactly the same purpose as for the `RemObjects.SDK.Extensions.Hosting.Microsoft` package.

The `RemObjects.SDK.Extensions.Hosting.Topshelf` package uses Dependency Injection container provided by the `Microsoft.Extnsions.DependencyInjection` package.

Topshelf framework provides a rich set of command line arguments, including commands to register the Windows Service:

```
NetServer.exe install -servicename:"NetService"

```

More commands and their options descriptions can be hound here: [http://docs.topshelf-project.com/en/latest/overview/commandline.html](http://docs.topshelf-project.com/en/latest/overview/commandline.html?ref=blogs.remobjects.com)

## Extensibility: Using custom Network Server implementation

The new infrastructure described in this article allows to define a custom implementation of pretty much any component used, starting from own `ICertificateGenerator` implementation up to the custom `IAppServerEngine` application core implementation. All what is required to do this is to re-register corresponding service in the services collection.

Still the most common task is to use a custom Network Server component implementation.

For example let's take a look at the following task:

> Server should expose its services on an additional server channel.

The first step is to implement the custom Network server itself. A very straightforward custom Network Server implementation would look like

```c#
public class ExtendedNetworkServer : NetworkServer
{
	private IpHttpServerChannel _serverChannel;

	protected override void InternalStart()
	{
		base.InternalStart();

		this._serverChannel = new IpHttpServerChannel();
		this._serverChannel.Port = this.Port + 1;
		this._serverChannel.Dispatchers.AddRange(
			this.ServerMessages.Select(
               m => new MessageDispatcher(m.DefaultDispatcherName, m)));
		this._serverChannel.Open();
	}

	protected override void InternalStop()
	{
		this._serverChannel.Close();
		base.InternalStop();
	}
}
```

The next step is to register this class as the one that should be used as a Network Server implementation at runtime. All what is needed to this is to provide the custom Network Server class as a generic parameter in the `UseNetworkServer` method call:

```c#
. . .
   .UseNetworkServer<ExtendedNetworkServer>(server =>
. . .
```

## Extensibility: Using custom App Server Engine implementation

AppServerEngine is a 'heart' of an application server. Its instance is used by Background Workers that implement the Windows Service to load the server configuration (including RODL composition), and to start or stop the NetworkServer instance.

In the very rare cases where a *very* deep customization is required, it is possible to use your own custom implementation of the `IAppServerEngine` interface.

Here is a sample implementation of a custom App Server Engine:

```c#
public class ExtendedAppServerEngine : AppServerEngine
{
	public ExtendedAppServerEngine(IServiceProvider serviceProvider, INetworkServer server,
			IAppServerConfiguration configuration, INetworkServerConfigurator networkServerConfigurator,
			ICertificateGenerator certificateGenerator)
	: base(serviceProvider, server, configuration, networkServerConfigurator, certificateGenerator)
	{
	}

	protected override void InternalStart()
	{
		System.Diagnostics.Debug.WriteLine(
            	"ExtendedAppServerEngine.InternalStart");

		base.InternalStart();
	}
}
```

Once defined, this class should be registered in the services collection as the implementation of the `IAppServerEngine` interface, replacing the default implementation registered by the `UseApplicationServer` method:

```c#
static void Main(string[] args)
{
	HostFactory.Run(host =>
	{
		host.ConfigureServices(services =>
		{
		});
		host.UseApplicationServer(configuration =>
		{
		});
		host.UseNetworkServer<ExtendedNetworkServer>(server =>
		{
		});

		// Register custom App Server Engine implementation
		host.ConfigureServices(services =>
		{
			services.Replace(
				ServiceDescriptor.Singleton<IAppServerEngine,
                		ExtendedAppServerEngine>());
		});

			host.UseHostedService();
	});
}
```

## Migration to the new Hosting infrastructure

It is very easy to migrate an existing ApplicationServer-based app to to the new Hosting-based packages infrastructure.

This can be done in a few simple steps:

1\. Remove all direct references to Remoting SDK or Data Abstract assemblies.

2\. Reference required NuGet packages ( `RemObjects.SDK.Server` or `RemObjects.DataAbstract.Server` accordingly).

3\. Reference the [RemObjects.SDK.Extensions.Hosting.Microsoft](http://remobjects.sdk.extensions.hosting.microsoft/?ref=blogs.remobjects.com) or `RemObjects.SDK.Extensions.Hosting.Topshelf` package depending on the hosting framework you want to use.

4\. Comment out existing `Program.Main` method

5\. Reintroduce the `Program.Main` method:

5.1\. For [RemObjects.SDK.Extensions.Hosting.Microsoft](http://remobjects.sdk.extensions.hosting.microsoft/?ref=blogs.remobjects.com) package

```c#
public static void Main(string[] args)
{
	var host = CreateHostBuilder(args)
		.Build();

	host.Run();
}

public static IHostBuilder CreateHostBuilder(string[] args)
{
	return Host.CreateDefaultBuilder(args)
			.ConfigureServices((hostContext, services) =>
			{
			})
			.UseApplicationServer(configuration =>
			{
			})
			.UseNetworkServer(server =>
			{
			})
			.UseConsoleLifetime();
}
```

5.2\. For [RemObjects.SDK.Extensions.Hosting.Topshelf](http://remobjects.sdk.extensions.hosting.microsoft/?ref=blogs.remobjects.com) package

```c#
static void Main(string[] args)
{
	HostFactory.Run(host =>
	{
		host.ConfigureServices(services =>
		{
		});
		host.UseApplicationServer(configuration =>
		{
		});
		host.UseNetworkServer(server =>
		{
		});

		host.UseHostedService();
	});
}
```

6\. Define necessary ApplicationServer and NetworkServer configuration options using methods `UseApplicationServer` and `UseNetworkServer` accordingly.

## Conclusion

The new Hosting infrastructure provides more clean API and is easier to use than the old ApplicationServer boilerplate code. It fits better into the new approaches used by .NET Core and .NET 5 runtimes as well.

The ApplicationServer boilerplate is aimed more at the "old" .NET Framework while the new Hosting infrastructure uses benefits of the newer .NET Core and .NET 5 runtimes, like the features provided by the Microsoft.Extensions packages or native support of Dependency Injection.

While ApplicationServer boilerplate won't be removed from Remote SDK or anyhow deprecated or marked as obsolete, for new projects it is better to consider to use the new Hosting infrastructure instead of the ApplicationServer boilerplate code.

See also [this topic in the documentation](https://docs.remotingsdk.com/Servers/Technologies/ApplicationHost/?ref=blogs.remobjects.com).