Liman 1.0.1

dotnet add package Liman --version 1.0.1
                    
NuGet\Install-Package Liman -Version 1.0.1
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="Liman" Version="1.0.1" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="Liman" Version="1.0.1" />
                    
Directory.Packages.props
<PackageReference Include="Liman" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add Liman --version 1.0.1
                    
#r "nuget: Liman, 1.0.1"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package Liman@1.0.1
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=Liman&version=1.0.1
                    
Install as a Cake Addin
#tool nuget:?package=Liman&version=1.0.1
                    
Install as a Cake Tool

What is it?

Liman is a library for C# that helps with Service Lifetime Management. This encompasses the following functionalities:

  • Service location/creation

  • Dependency injection

  • Service disposal

  • And more...

Main features

This chapter will give you a brief overview of the main features of Liman. For more detailed information, please check out the Wiki.

Registration via Attribute

In Liman, the most common way to register your service implementation will be by adding an attribute to your class. This keeps information about the lifetime of your class inside the file that contains the class. Allowing you to adhere better to the single responsibility principle.

[LimanService]
public class MyServiceImplementation : IMyService
{
}

Constructor injection

Constructor injection is the main way to get access to services. This ensures you have immediate access to services that you depend on.

[LimanService]
internal class MyServiceWithInjection
{
    private IMyService myService;

    public MyServiceWithInjection(IMyService myService)
    {
        this.myService = myService;
    }
}

Lifetime management

Liman will automatically clean up your disposables when they are no longer used, or at least when your application is finished. Even if the service that uses it, is not disposable.

[LimanService]
public class MyDisposableService : IMyDisposableService, IDisposable
{
    public void Dispose()
    {
        // Code to clean up stuff
    }
}
[LimanService]
internal class MyNotDisposableService
{
    private IMyDisposableService myService;

    public MyNotDisposableService(IMyDisposableService myService)
    {
        this.myService = myService;
    }
}

Program.cs

using Liman;
using System.Reflection;

var serviceCollection = LimanFactory.CreateServiceCollection();
serviceCollection.Add(Assembly.GetExecutingAssembly());
var application = LimanFactory.CreateApplication(serviceCollection);
application.Run();

It will also automatically load (and run) your application services.

[LimanService(LimanServiceLifetime.Application)]
internal class MyApplicationService : ILimanRunnable
{
    private readonly IMyService service;
    private bool isRunning = true;

    public MyApplicationService(IMyService service)
    {
        this.service = service;
    }

    public void Run()
    {
        Console.WriteLine("Press 'Enter' to do something, or type 'quit' to exit.");

        while (isRunning)
        {
            var line = Console.ReadLine();

            if (line == "quit")
            {
                isRunning = false;
            }
            else
            {
                service.DoSomething();
            }
        }
    }
}
[LimanService(LimanServiceLifetime.Application)]
internal class ApplicationLogger : ILimanInitializable, IDisposable
{
    public void Initialize()
    {
        Console.WriteLine("Application started");
    }
    
    public void Dispose()
    {
        Console.WriteLine("Application stopped");
    }   
}

And if you are creating services outside of constructor injection, make sure you let the service provider know when you don't use it anymore. This ensures that everything is disposed of properly.

[LimanService(LimanServiceLifetime.Application)]
internal class ServiceUser
{
    private ILimanServiceProvider serviceProvider;
    private IMyService? service;

    public ServiceUser(ILimanServiceProvider serviceProvider)
    {
        this.serviceProvider = serviceProvider;
    }
    
    public void CreateNew()
    {
        // remove old service
        if (service != null) serviceProvider.RemoveService(service);
        
        // create new service
        service = serviceProvider.GetRequiredService<IMyService>();
    }   
}

Custom arguments

In some cases you may need dependency injection and arguments in the same constructor. You can use the NoInjectionAttribute for this.

Keep in mind that you have to put your custom parameters at the end of the constructor. And when creating the service, you need to enter the arguments in the same order.

[LimanService(LimanServiceLifetime.Transient)]
internal class CustomParametersService(IMyService aService, [NoInjection] string name)
{
    public IMyService AService { get; } = aService;
    public string Name { get; } = name;
}
[LimanService]
internal class CustomParametersFactory(ILimanServiceProvider serviceProvider)
{
    public CustomParametersService Create(string name)
    {
        return serviceProvider.GetRequiredService<CustomParametersService>(name);
    }

    public void Delete(CustomParametersService serviceToDelete)
    {
        serviceProvider.RemoveService(serviceToDelete);
    }
}
Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  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. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
1.0.1 126 7/17/2025
1.0.0 159 5/21/2025