Skip to content

Getting Started

Jim Burlison edited this page Dec 5, 2025 · 2 revisions

Getting Started

This guide will help you get SSDI up and running in your .NET project.

Installation

Using .NET CLI

dotnet add package SSDI

Using Package Manager ConsoleRthre

Install-Package SSDI

Using PackageReference

Add to your .csproj file:

<PackageReference Include="SSDI" Version="*" />

Requirements

  • .NET 8.0 or later
  • .NET 10.0 supported with additional optimizations

Basic Usage

Step 1: Create a Container

using SSDI;

var container = new DependencyInjectionContainer();

Optional: Enable Eager Compilation

For maximum resolution performance, enable EagerCompilation:

var container = new DependencyInjectionContainer { EagerCompilation = true };

Lazy compilation is the default and offers faster registration with slower first-time resolution. Eager compilation pre-compiles all factories during Configure(), resulting in faster resolution but slower registration.

Mode Resolution Registration
Lazy (default) ~41 ns ~27 μs
Eager ~19 ns ~10 ms

See Performance for detailed benchmarks.

Step 2: Register Services

Use the Configure method to register your services:

container.Configure(c =>
{
    c.Export<MyService>();
    c.Export<MyRepository>();
});

Step 3: Resolve Services

Use Locate<T>() to resolve registered services:

var service = container.Locate<MyService>();

Complete Example

using SSDI;

// Define your services
public interface ILogger
{
    void Log(string message);
}

public class ConsoleLogger : ILogger
{
    public void Log(string message) => Console.WriteLine(message);
}

public class GameEngine
{
    private readonly ILogger _logger;

    public GameEngine(ILogger logger)
    {
        _logger = logger;
    }

    public void Start()
    {
        _logger.Log("Game engine started!");
    }
}

// Setup and use the container
var container = new DependencyInjectionContainer();

container.Configure(c =>
{
    c.Export<ConsoleLogger>().As<ILogger>().Lifestyle.Singleton();
    c.Export<GameEngine>().Lifestyle.Singleton();
});

var engine = container.Locate<GameEngine>();
engine.Start(); // Output: "Game engine started!"

Understanding Registration

Registering Concrete Types

Register a class directly:

container.Configure(c =>
{
    c.Export<MyService>();
});

Registering Interfaces

Map an implementation to an interface:

container.Configure(c =>
{
    c.Export<SqlRepository>().As<IRepository>();
});

Multiple Registrations

You can call Configure multiple times:

container.Configure(c =>
{
    c.Export<CoreService>();
});

// Later in your code...
container.Configure(c =>
{
    c.Export<PluginService>();
});

Understanding Lifetimes

SSDI supports three service lifetimes:

Lifetime Description Use Case
Transient New instance every resolution (default) Stateless services, short-lived objects
Singleton Single instance for app lifetime Configuration, shared state, engines
Scoped One instance per scope Per-request, per-player services
container.Configure(c =>
{
    c.Export<TransientService>();                    // New instance each time
    c.Export<SingletonService>().Lifestyle.Singleton(); // Shared instance
    c.Export<ScopedService>().Lifestyle.Scoped();    // Per-scope instance
});

Dependency Resolution

SSDI automatically resolves constructor dependencies:

public class UserService
{
    private readonly IRepository _repo;
    private readonly ILogger _logger;

    public UserService(IRepository repo, ILogger logger)
    {
        _repo = repo;
        _logger = logger;
    }
}

container.Configure(c =>
{
    c.Export<SqlRepository>().As<IRepository>();
    c.Export<ConsoleLogger>().As<ILogger>();
    c.Export<UserService>();
});

// Both dependencies are automatically injected
var userService = container.Locate<UserService>();

Checking Registration

Verify if a type is registered before resolving:

if (container.IsRegistered<ILogger>())
{
    var logger = container.Locate<ILogger>();
}

Automatic Resolution

SSDI can resolve unregistered types with parameterless constructors:

public class SimpleService
{
    public SimpleService() { }
}

// Works even without explicit registration
var service = container.Locate<SimpleService>();

Next Steps

Common Patterns

Application Startup

public class Program
{
    private static DependencyInjectionContainer _container;

    public static void Main()
    {
        _container = new DependencyInjectionContainer();
        ConfigureServices(_container);

        var app = _container.Locate<Application>();
        app.Run();
    }

    private static void ConfigureServices(DependencyInjectionContainer container)
    {
        container.Configure(c =>
        {
            // Core services
            c.Export<Application>().Lifestyle.Singleton();
            c.Export<ConfigurationManager>().Lifestyle.Singleton();

            // Feature services
            c.Export<UserManager>().As<IUserManager>();
            c.Export<DataProcessor>();
        });
    }
}

Game Loop Integration

var container = new DependencyInjectionContainer();

container.Configure(c =>
{
    c.Export<GameEngine>().Lifestyle.Singleton();
    c.Export<InputHandler>().Lifestyle.Singleton();
    c.Export<Renderer>().Lifestyle.Singleton();
});

var engine = container.Locate<GameEngine>();

while (engine.IsRunning)
{
    engine.Update();
    engine.Render();
}