IoCTools.Abstractions 0.2.6

There is a newer version of this package available.
See the version list below for details.
dotnet add package IoCTools.Abstractions --version 0.2.6
                    
NuGet\Install-Package IoCTools.Abstractions -Version 0.2.6
                    
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="IoCTools.Abstractions" Version="0.2.6" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="IoCTools.Abstractions" Version="0.2.6" />
                    
Directory.Packages.props
<PackageReference Include="IoCTools.Abstractions" />
                    
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 IoCTools.Abstractions --version 0.2.6
                    
#r "nuget: IoCTools.Abstractions, 0.2.6"
                    
#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 IoCTools.Abstractions@0.2.6
                    
#: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=IoCTools.Abstractions&version=0.2.6
                    
Install as a Cake Addin
#tool nuget:?package=IoCTools.Abstractions&version=0.2.6
                    
Install as a Cake Tool

IoCTools

This repository provides various useful tools for simplifying and streamlining the process of work with Inversion of Control in .NET; mainly focusing on working with ASP.NET's Services. This project provides a source generator which eliminates much of the boilerplate that normally comes with working with services in .NET.

IoC Tools IoC Abstractions

Features

Although the project is in alpha and under active development, some features are already working.

Self Describing Services

When it comes to service API design, it is often written with a specific service lifetime in mind. For example, services that persist values during the app session are aware implicitly by their design that they only support a singleton service lifetime.

It therefore makes the most sense to let the service define what lifetime it expects to be given. Given the following example service that must operate as a singleton, the before code demonstrates how registering the service without IoC Tools would go:

// in the service class
namespace SampleProject.Services;

public class SomeService : ISomeService
{
    private readonly int _someValue = 1;
}

// in Program.cs
builder.Services.RegisterSingleton<ISomeService, SomeService>();

This example is not ideal as the service does not get to choose its lifetime, which is its concern as it is designed with one particular service in mind.

With IoC.Tools, you may refactor the above service as follows:

// in the service class
namespace SampleProject.Services;

[Service(Lifetime.Singleton)]
public partial class SomeService : ISomeService
{
    private readonly int _someValue = 1;
}

// in Program.cs
builder.Services.RegisterSampleProjectServices();

This eliminates the need for the setup code in program.cs to have any understanding of the designed lifetime of the service, and lets the service own its own design explicitly.

Intuitive Dependency Injection

In the case where your service depends on other services, the following code is normally required to bring in those dependencies.

In the following code, we see the (recently improved with primary constructor) syntax required to bring in a non trivial amount of dependencies.

// in the service class
namespace SampleProject.Services;

public class SomeService(IOtherService otherService, IAnotherService anotherService, 
    IYetAnotherService yetAnotherService, ISomehowAnotherService somehowAnotherService) 
    : ISomeService
{
    private readonly int _someValue = 1;
    
    public void Test()
    {
        // use services 
    }
}

Let's not forget the 'olden days' where it was even worse:

// in the service class
namespace SampleProject.Services;

public class SomeService : ISomeService
{
    private readonly IOtherService _otherService;
    private readonly IAnotherService _anotherService;
    private readonly IYetAnotherService _yetAnotherService;
    private readonly ISomehowAnotherService _somehowAnotherService);
        
    public SomeService(IOtherService otherService, IAnotherService anotherService, 
    IYetAnotherService yetAnotherService, ISomehowAnotherService somehowAnotherService)
    {
        _otherService = otherService;
        _anotherService = anotherService;
        _yetAnotherService = yetAnotherService;
        _somehowAnotherService = somehowAnotherService;
    }
    private readonly int _someValue = 1;
    
    public void Test()
    {
        // use services 
    }
}

That always seemed like an egregious amount of boilerplate.

With IoC Tools, you may refactor the above code to the following:

// in the service class
namespace SampleProject.Services;

[Service]
public partial class SomeService : ISomeService
{
    [Inject] private readonly IOtherService _otherService;
    [Inject] private readonly IAnotherService _anotherService;
    [Inject] private readonly IYetAnotherService _yetAnotherService;
    [Inject] private readonly ISomehowAnotherService _somehowAnotherService);

    private readonly int _someValue = 1;
    
    public void Test()
    {
        // use services 
    }
}

A source generator creates the appropriate constructor behind the scenes, saving the developer from having to experience bloated constructors.

This is still explicit enough that you can can clearly see even from a git diff that dependencies are coming in, but doesn't feel repetitive, and still allows the user to customize the names of their dependency field as well.

Although this project is still in development, IoC Tools already has support for injection of dependencies that have any generic depth.

// in the service class
namespace SampleProject.Services;

[Service]
public partial class SomeService : ISomeService
{
    [Inject] private readonly IEnumerable<IOtherService> _otherServices;

    private readonly int _someValue = 1;
    
    public void Test()
    {
        // use services 
    }
}

This code would work just as well.

Streamlined Service Registration

Another major boilerplate concern is the need to individually register each service in the setup code, or in a separate file.

It doesn't feel like good code- it is bloated and repetitive.

With IoC Tools, any class decorated with [Service] will automatically be added a new extension method on IServiceCollection that enables the user to simply decorate their services once (which you'd want to do anyway for resolving dependencies) and have a single method call in the setup code which adds all the services from the project.

The method is named after the project folder name due to a potential clash that would arise from having one project using IoC Tools being referenced by another project which also uses IoC Tools.

The project folder name was chosen as source generators have limitations on determining the root namespace or actual project name.

Given a project in a folder called SampleProject, the following would be doable in Program.cs:

// in the service class
// in Program.cs
builder.Services.RegisterSampleProjectServices();

As services are added or removed during development, IoC tools will automatically generate the appropriate changes in its extension method.

This is also how services can indicate their desired lifetime- using [Service(Lifetime.Singleton)] or [Service(Lifetime.Transient)] or [Service(Lifetime.Scoped)]. IoC Tools will automatically use the correct registration method.

Registration of generic services is not supported as this time. This is due to the fact that there is no way to infer which generic type should be supplied for the generic argument(s) without a new way to specify them manually.

Development

Development is currently active, and while there are public NuGet packages, they are marked with pre v1 versioning to indicate their instability.

As such, it should be expected that breaking API changes may occur.

Feel free to suggest ideas or bugfixes in the issues!

For more examples of the generator in action, clone down the repo and look at the Sample project.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  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. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
  • .NETStandard 2.0

    • No dependencies.

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.9.1 90 5/23/2026
1.8.0 1,297 5/12/2026
1.7.3 1,569 5/6/2026
1.7.2 88 5/6/2026
1.7.1 94 5/6/2026
1.6.1 98 4/29/2026
1.6.0 91 4/29/2026
1.5.1 143 4/12/2026
1.4.0 211 3/21/2026
1.3.0 118 1/24/2026
1.2.0 403 11/18/2025
1.1.0 294 11/12/2025
1.0.0 198 9/10/2025
1.0.0-alpha 243 8/28/2025
0.4.1 177 11/30/2024
0.4.0 150 11/30/2024
0.3.0 214 3/18/2024
0.2.6 187 2/6/2024
0.2.5 309 2/6/2024
0.2.4 184 2/6/2024
Loading failed

Initial alpha release