> ## 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.

# Dependency Injection in Remoting SDK for .NET (Part II)
- URL: https://blogs.remobjects.com/2020/11/03/untitled-2/
- Published: 2020-11-03T17:43:43.000Z
- Updated: 2020-11-03T17:43:43.000Z
- Author: Anton Kasyanov
- Tags: #Import 2026-08-17 20:17

This second part of our [series on DI](https://blogs.remobjects.com/p/eb12ce48-ddea-480c-827e-38e380a1772f/) will be a bit more technical. It will discuss new APIs provided by Remoting SDK, their performance and other technical details.

The first question that might arise is "What if I do not need all this stuff? My application is very simple so I just want to use the approaches I am used to."

Well, the answer is simple - just do not do anything. We have designed DI support to be as unobtrusive and transparent as possible so all existing code will work without any changes. Nothing will break. Also there are no performance hits or broken code in the case you won't touch DI container in your code.

Under the hood, Remoting SDK will do all the work for you. In fact, all these years SDK already did use a code that did act like a DI container, just a very simple one.

So, to begin with, let's take a closer look at the initialization code from the end of the part I:

```csharp
var container = new SimpleContainer();
container.RegisterSingleton(typeof(ILogger), new DebugLogger());
container.RegisterSDK(server.NetworkServer);
container.RegisterServices();
server.DependencyResolver = container;

```

Here, an instance of Remoting SDK built-in container is created.

Then a singleton registration call is performed. The container will register an instance of the `DebugLogger` class as implementing the `ILogger` interface. After this registration, that instance will be used as a parameter value while instantiating any types registered in the DI container.

The `RegisterSDK` method is an extension method that registers `SessionManager` and `EventSinkManager` instances in the container. Note that passing a `INetworkServer` instance as a parameter of this method ensures that Application Server initializes its `NetworkServer` instance and its `SessionManager` and `EventSinkManager` instances before they are registered in the container.

Then a `RegisterServices` call is issued. This extension method finds all non-abstract SDK services in the server application and registers them in the container.

The `SimpleContainer` can register SDK services on the fly, so this call can be omitted. Still it is highly recommended to call the `RegisterServices` method anyway. In this case `SimpleContainer` will validate all services registrations, so any container misconfiguration will be detected immediately at server application startup.

For example let's take a look at the code snippet above. Commenting out both `.RegisterSingleton` and `.RegisterServices` will allow the server application to start. Unfortunately any `FooService` call will fail because its constructor requires an `ILogger` instance while there is none provided. The main issue here is that an exception will be raised **only when the service is called**.

However, uncommenting the `.RegisterServices` call will result in the server application failing **immediately at startup**, allowing you to easily detect and fix any misconfiguration.

## Containers Without ApplicationServer

Older server applications (ones that do not use the [Application Server boilerplate](https://docs.remotingsdk.com/Servers/Concepts/ApplicationServer/?ref=blogs.remobjects.com) infrastructure) can also benefit from container support.

The `server.DependencyResolver` property used in the code earlier is just an alias for the `RemObjects.SDK.Server.Engine.ObjectActivator` static property. So this code will allow to configure a DI container as well:

```csharp
var container = new SimpleContainer();
container.RegisterSingleton(typeof(ILogger), new DebugLogger());
container.RegisterSDK(server.NetworkServer);
container.RegisterServices();
RemObjects.SDK.Server.Engine.ObjectActivator = container;

```

**A reminder**: There is no need to add any code to your existing apps. All existing apps will continue to work without any code changes required.

## Registration API

Remoting SDK and Data Abstract provide a number of methods that simplify the task of registering SDK services and infrastructure in the DI container. These methods are declared as extension methods, so it is possible to easily switch from the Remoting SDK container to any 3rd party DI container like Unity with as less code changes as possible.

Methods:

- `RemObjects.SDK.Server` namespace
  - `RegisterSDK(INetworkServer)` \- registers `SessionManager` and `EventSinkManager` instances used by the provided `INetworkServer` instance
  - `RegisterServices` \- register all non-abstract SDK services defined in the server application
- `RemObjects.DataAbstract.Server` namespace
  - `RegisterDataAbstract` \- registers ConnectionManager instance. Also registers an `ILocalServiceActivator` instance (see below).

The `ILocalServiceActivator` interface provides a set of helper methods that should simplify acquiring local Data Services. At this moment the default implementation of this interface provides 2 methods that are aliases of the corresponding `RemObjects.DataAbstract.Server.Engine` methods: `AcquireService` and `ReleaseService`

## Simple Container, Described

The built-in DI container exposes the following methods:

```csharp
void Register(Type serviceType);
void Register(Type serviceType, Type implementationType);
void Register(Type serviceType, Func<Object> factory);

void RegisterSingleton(Type serviceType);
void RegisterSingleton(Type serviceType, Type implementationType);
void RegisterSingleton(Type serviceType, Object instance);

void Register<TService>();
void Register<TService, TImplementation>();
void Register<TService>(Func<Object> factory);

void RegisterSingleton<TService>();
void RegisterSingleton<TService, TImplementation>();
void RegisterSingleton<TService>(TService instance);

```

The `Register` methods allow you to register types that should be instantiated anew on every request (like SDK services):

- `Register(Type serviceType)` \- registers `serviceType` in the container
  - `RegisterSingleton(Type serviceType)` \- registers singleton of type `serviceType`
  - `RegisterSingleton(Type serviceType, Type implementationType)` \- registers singleton of `serviceType` as the type implementing the `implementationType`. Can be used to register the concrete implementation of abstract base class.
  - `RegisterSingleton(Type serviceType, Object instance)` \- registers the concrete instance as the `serviceType` implementation.
  - `Register(Type serviceType)` \- registers the `serviceType` in the container.
  - `RegisterSingleton(Type serviceType, Object instance)` \- registers the concrete instance as the `serviceType` implementation.

`Register(Type serviceType, Type implementationType)` \- registers `implementationType` in the container as a type implementing the `implementationType`, Func factory)` - registers the`serviceType\` in the container and sets a custom method that should be used to instantiate it. Can be used if the class being registered requires special actions to be instantiated (f.e. a type should be instantiated via a factory method call)The `RegisterSingleton` methods allow you to register types that should be instantiated only once:Generic methods are used as aliases for their non-generic versions.

## Integration of 3rd-party Containers

It is possible to use almost any 3rd part Dependency Injection container instead of the built-in Remoting SDK container.The recommended approach is to create a wrapper class around the container implementing one of the `IDependencyContainer` or `IObjectActivator` interfaces. Then this wrapper instance should be assigned to either the `server.DependencyResolver` property (for `IDependencyContainer` implementation) or directly to the `RemObjects.SDK.Server.Engine.ObjectActivator` property.The `IObjectActivator` exposes a single `GetInstance` method. This method accepts a service type and returns an instance of this type.The `IDependencyContainer` interface provides 2 additional methods:In most cases it is recommended to implement the `IDependencyContainer` interface as it will allow you to use the Registration API methods, saving you from manually writing the code required to register SDK services and SDK/DA infrastructure.

### Sample Wrappers: `LightInject`

This is a sample wrapper for the `LightInject` ([https://www.lightinject.net/](https://www.lightinject.net/?ref=blogs.remobjects.com)) DI container:

```csharp
public sealed class LightInjectContainer : IDependencyContainer
{
	private readonly ServiceContainer _container;

	public LightInjectContainer()
	{
		this._container = new ServiceContainer(ContainerOptions.Default);
	}

	public object GetInstance(Type objectType)
	{
		return this._container.GetInstance(objectType);
	}

	public void Register(Type serviceType)
	{
		this._container.Register(serviceType);
	}

	public void RegisterSingleton(Type serviceType, object instance)
	{
		this._container.RegisterInstance(serviceType, instance);
	}
}

```

Once defined this container wrapper can be used as:

```csharp
var container = new LightInjectContainer();
container.RegisterSingleton(typeof(ILogger), new DebugLogger());
container.RegisterSDK(server.NetworkServer);
container.RegisterServices();
server.DependencyResolver = container;

```

Note how easy it to replace the DI container used.

### Sample Wrappers: `Autofac`

As another example let's look at Autofac ([https://autofac.org/](https://autofac.org/?ref=blogs.remobjects.com)):A wrapper class for this DI container would look like this:

```csharp
public sealed class AutofacContainer : IDependencyContainer
{
	private IContainer _container;
	private ContainerBuilder _builder;

	public AutofacContainer()
	{
		this._builder = new ContainerBuilder();
	}

	public void Build()
	{
		this._container = this._builder.Build();
		this._builder = null;
	}

	public object GetInstance(Type objectType)
	{
		return this._container.Resolve(objectType);
	}

	public void Register(Type serviceType)
	{
		this._builder.RegisterType(serviceType);
	}

	public void RegisterSingleton(Type serviceType, object instance)
	{
		this._builder.Register(_ => instance).As(serviceType).SingleInstance();
	}
}

```

This wrapper requires an additional container-specific step to be used:

```csharp
var container = new AutofacContainer();
container.RegisterSingleton(typeof(ILogger), new DebugLogger());
container.RegisterSDK(server.NetworkServer);
container.RegisterServices();
container.Build(); // This call performs actual Autofac container initialization
server.DependencyResolver = container;

```

Still most of the code is the same for any DI container used.

## Conclusion

We hope that you will find your use for this feature and that Dependency Injection containers support will help you to write even more reliable and clean code.Any feedback will be highly appreciated.