com.alexey-developer89.Autofac2ZenjectLikeBridge 2.0.0

Suggested Alternatives

ZenAutofac

Additional Details

same package, but name is different, as well as id and namespace
+bugfixes

dotnet add package com.alexey-developer89.Autofac2ZenjectLikeBridge --version 2.0.0
                    
NuGet\Install-Package com.alexey-developer89.Autofac2ZenjectLikeBridge -Version 2.0.0
                    
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="com.alexey-developer89.Autofac2ZenjectLikeBridge" Version="2.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="com.alexey-developer89.Autofac2ZenjectLikeBridge" Version="2.0.0" />
                    
Directory.Packages.props
<PackageReference Include="com.alexey-developer89.Autofac2ZenjectLikeBridge" />
                    
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 com.alexey-developer89.Autofac2ZenjectLikeBridge --version 2.0.0
                    
#r "nuget: com.alexey-developer89.Autofac2ZenjectLikeBridge, 2.0.0"
                    
#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 com.alexey-developer89.Autofac2ZenjectLikeBridge@2.0.0
                    
#: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=com.alexey-developer89.Autofac2ZenjectLikeBridge&version=2.0.0
                    
Install as a Cake Addin
#tool nuget:?package=com.alexey-developer89.Autofac2ZenjectLikeBridge&version=2.0.0
                    
Install as a Cake Tool

Autofac2ZenjectLikeBridge

NuGet Version License: MIT

Brings the power of Zenject's subcontainers syntax to Autofac, enabling Zenject-style dependency injection patterns in your Autofac applications. This library provides a familiar API for developers who love Zenject's approach to scoping and subcontainers but want to leverage Autofac's robust dependency injection capabilities.

🚀 Key Features

  • Zenject-inspired subcontainer syntax for Autofac
  • Subcontainer lifetime management
  • Seamless integration of Zenject's scoping patterns
  • Simplified decorator registration with isolated scopes
  • Full compatibility with existing Autofac applications
  • IFactory<...> and PlaceholderFactory<...> for factory registration with subcontainer support

💡 Why Use Autofac2ZenjectLikeBridge?

This library is ideal for:

  • Teams transitioning from Zenject to Autofac
  • Projects that want to combine the best of both DI containers
  • Developers who prefer Zenject's subcontainer API but need Autofac's features
  • Applications requiring advanced dependency injection scenarios with clean scoping

đŸ“Ļ Installation

Install the package from NuGet:

Install-Package com.alexey-developer89.Autofac2ZenjectLikeBridge

Or via the .NET CLI:

dotnet add package com.alexey-developer89.Autofac2ZenjectLikeBridge

đŸ› ī¸ Quick Start

// Create your container builder
var builder = new ContainerBuilder();

// Register your service from subcontainer
builder
    .RegisterExtended<ISampleService>()
    .FromSubScope()
    .ByFunction(
        subcontainerBuilder =>
        {
            // Register service in the subcontainer
            // registered type should match type in RegisterFromSubScope
            subcontainerBuilder
                .RegisterType<SampleService>()
                .As<ISampleService>()
                .SingleInstance();

            // Register dependencies in the subcontainer
            // needed to run SampleService
            subcontainerBuilder
                .RegisterType<SampleDependency>()
                .SingleInstance();
        });

// ...

using var container = builder.Build();

container.Resolve<ISampleService>();

📚 Documentation

â„šī¸ Info: All instances resolved from subcontainers have to implement IDisposable interface. This needed to limit subcontainers lifetime. When instance is disposed, it's subcontainer will be disposed too. Instance's Dispose method will be called patched via Harmony library, more information here.

Creating Subcontainers

Create isolated subcontainers for instance. Based on Autofac's lifetime scope. Scope will inherit all dependencies from parent scope(s). In the same time scope could have own dependencies, that will be available only in this scope. See Quick Start for code sample. When FromSubScope() called it supposed to create new nested ILifetimeScope register required type and all it dependencies and resolve that type form created subcontainer. In other words target type have to be registered in subcontainer installer and implements IDisposable

Overall structure

Modules

Autofac's modules could be used to register types in subcontainers. Module sample:

class SampleServiceModule : Module
{
    private readonly object _data;

    //pass all parameters to module's constructor as well as extra parameters or dependencies
    //from parent DI container(s)
    public SampleServiceModule(object data)
    {
        _data = data;
    }

    protected override void Load(ContainerBuilder builder)
    {
        //do ISampleService registration here
    }
}
Simple registrations:
builder
    .RegisterExtended<ISampleService>()
    .FromSubScope()
    .ByModule<SampleServiceModule>();

or even create module with using service provider. In that case module will be created in subcontainer and all dependencies from current scope will be available in the module.

builder
    .RegisterExtended<ISampleService>()
    .FromSubScope()
    .ByModule<SampleServiceModule>((scope) => scope.CreateInstance<SampleServiceModule>(parameter));

Decorators

Simple

Autofac default:

builder
    .RegisterDecorator<ServiceDecorator, IService>();
From Function

Use function to create decorator instance:

builder
    .RegisterDecoratorExtended<ServiceDecorator, IService>()
    .FromFunction(
        (context, baseService) =>
        {
            var parameters = new Parameters();

            return context.CreateInstance<ServiceDecorator>(baseService, parameters);
        });
With Subcontainer
ByFunction

Use subcontainer to create decorator:

builder
    .RegisterDecoratorExtended<ServiceDecorator, IService>()
    .FromSubScope()
    .ByFunction(
        (subcontainerBuilder, baseService) =>
        {
            // Register service in the subcontainer
            // registered type should match type in RegisterFromSubScope
            subcontainerBuilder
                .RegisterType<ServiceDecorator>()
                .WithParameters(TypedParameter.From(baseService))
                .SingleInstance();

            // Register dependencies in the subcontainer
            // needed to run ServiceDecorator
            subcontainerBuilder
                .RegisterType<SampleDependency>()
                .SingleInstance();
        });
By Module

As well instances could be created from module, decorator could also be created from module: In that case decoratable service will be passed to module constructor. Module sample:

class ServiceDecoratorModule : Module
{
    private readonly object _data;
    private readonly IService _service;

    //pass all parameters and decoratable service to module's constructor as well as extra parameters or dependencies
    //from parent DI container(s)
    public ServiceDecoratorModule(IService service, object data)
    {
        _data = data;
        _service = service;
    }

    protected override void Load(ContainerBuilder builder)
    {
        //do ServiceDecorator registration here
    }
}

registration sample:

builder
    .RegisterDecoratorExtended<ServiceDecorator, IService>()
    .FromSubScope()
    .ByModule<ServiceDecoratorModule>();

registration via service provider:

builder
    .RegisterDecoratorExtended<ServiceDecorator, IService>()
    .FromSubScope()
    .ByModule((scope, service) => scope.CreateInstance<ServiceDecoratorModule>(service, parameter));

Factories

IFactory

Provides interface IFactory<parameter1, parameter2, ... , parameterN, Iinstance> where parameter1, parameter2, ... , parameterN are parameters for factory creation and Iinstance is instance type.

From Functions

Use function to register IFactory<Iinstance> in DI:

builder
    .RegisterIFactoryExtended<Iinstance>()
    .FromFunction(
        scope => new Instance
        {
            Data = Guid.NewGuid()
        });

Use function to register IFactory<Guid, Iinstance> in DI:

builder
    .RegisterIFactoryExtended<Guid, Iinstance>()
    .FromFunction(
        (scope, parameter) => new Instance
        {
            Data = parameter
        });
From Subcontainers

Use subcontainer to create factory IFactory<Iinstance>, new subcontainer will be created when factory's Create method is called:

By Function
builder
    .RegisterIFactoryExtended<Iinstance>()
    .FromSubScope()
    .ByFunction(subcontainerBuilder =>
    {
        // Register service in the subcontainer
        // registered type should match type in RegisterFactoryFromSubScope
        subcontainerBuilder
            .RegisterType<Iinstance>()
            .SingleInstance();

        // Register dependencies in the subcontainer
        // needed to run Iinstance
        subcontainerBuilder
            .RegisterType<SampleDependency>()
            .SingleInstance();
    });

Parameters edition:

builder
    .RegisterIFactoryExtended<Guid, Iinstance>()
    .FromSubScope()
    .ByFunction((subcontainerBuilder, parameter) =>
    {
        // Register service in the subcontainer
        // registered type should match type in RegisterFactoryFromSubScope
        subcontainerBuilder
            .RegisterType<Iinstance>()
            .WithParameters(TypedParameter.From(parameter))
            .SingleInstance();

        // Register dependencies in the subcontainer
        // needed to run Iinstance
        subcontainerBuilder
            .RegisterType<SampleDependency>()
            .SingleInstance();
    });
By Module

Registration factories to resolve from module. All parameters will be passed to module's constructor. Module sample:

class ServiceModule : Module
{
    private readonly string _data;

    //pass all parameters to module's constructor as well as extra parameters or dependencies
    //from parent DI container(s)
    public ServiceModule(string data)
    {
        _data = data;
    }

    protected override void Load(ContainerBuilder builder)
    {
        //do IService registration here
    }
}

Registration sample:

builder
    .RegisterIFactoryExtended<string, IService>()
    .FromSubScope()
    .ByModule<ServiceModule>();

Registration sample with extra parameters via service provider:

builder
    .RegisterIFactoryExtended<string, IService>()
    .FromSubScope()
    .ByModule<ServiceModule>(
        (scope, arg3)
            => scope.CreateInstance<ServiceModule>(arg3, extraParameter));
Placeholders Factories

Used for registration of type distinct from interface IFactory<T>, and/or modify factory Create behavior, like some instance initialization: Create new class and inherit from PlaceholderFactory<T>:

class MyCustomFactory : PlaceholderFactory<Iinstance>
{
    public MyCustomFactory(SomeDependency dependency)
    {
        //...
    }

    //you can override Create method
    public override Iinstance Create()
    {
        return base.Create();
    }
}
From Functions

Placeholders Factories registration is available from function:

builder
    .RegisterPlaceholderFactoryExtended<Iinstance, MyCustomFactory>()
    .FromFunction(
        scope => new Instance
        {
            Data = Guid.NewGuid()
        });
From Subcontainers

and for subcontainers, new subcontainer will be created and installer called to register all content in subcontainer

By Function

via function

builder
    .RegisterPlaceholderFactoryExtended<
        Guid,
        Iinstance,
        MyCustomFactory>()
    .FromSubScope()
    .ByFunction((subcontainerBuilder, parameter) =>
    {
        // Register service in the subcontainer
        // registered type should match type in RegisterPlaceholderFactoryExtended
        subcontainerBuilder
            .RegisterType<Iinstance>()
            .WithParameters(TypedParameter.From(parameter))
            .SingleInstance();

        // Register dependencies in the subcontainer
        // needed to run Iinstance
        subcontainerBuilder
            .RegisterType<SampleDependency>()
            .SingleInstance();
    });
By Module

For module sample see by module section in IFactory registration. The registration is similar to IFactory registration. And could reuse same modules.

Registration sample:

builder
    .RegisterPlaceholderFactoryExtended<string, IService, MyCustomServiceFactory>()
    .FromSubScope()
    .ByModule<ServiceModule>();

Registration sample with extra parameters via service provider:

builder
    .RegisterPlaceholderFactoryExtended<string, IService, MyCustomServiceFactory>()
    .FromSubScope()
    .ByModule<ServiceModule>(
        (scope, arg3)
            => scope.CreateInstance<ServiceModule>(arg3, extraParameter));

where placeholder factory type is

class MyCustomServiceFactory : PlaceholderFactory<string, IService>
{
    public MyCustomServiceFactory(SomeDependency dependency)
    {
        //...
    }

    //you can override Create method
    public override IService Create(string arg)
    {
        return base.Create(arg);
    }
}

Other Helpers

CompositeDisposable

Use CompositeDisposable for services and decorators to manage multiple disposables and comply with IDisposable and ICollection<IDisposable>. CompositeDisposable will dispose all disposables, added to it, when disposed.

Example:

var composite = new CompositeDisposable();

_disposable1.AddTo(composite);
_disposable2.AddTo(composite);

//_disposable1 & _disposable2 will be disposed here
composite.Dispose();
IComponentContext.CreateInstance

Use IComponentContext.CreateInstance to create instance of type with using DI container:

builder
    .Register<SampleService>(context =>
    {
        var result = context.CreateInstance<SampleService>(Guid.NewGuid());

        result.Setup();

        return result;
    })
    .As<ISampleService>()
    .SingleInstance();

As mentioned before each instance resolved from subcontainer have to implement IDisposable interface. And subcontainer will be disposed when instance is disposed. To achieve this behavior HarmonyPatch is used.
It can add a finalizer to the instance A and set a reference to the instance B. When instance B will be disposed A will be disposed too.
That behavior is accessible via A.AddToHarmony(B) method. In that case B will be patched if not patched yet.
To force patch, in order to improve performance, use HarmonyPatch.EnsurePatched(typeof(B)) when program starts. Or use HarmonyPatch.PatchNonLazy() method to patch all types (in that case generic will not be patched).

🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/AmazingFeature)
  3. Commit your changes (git commit -m 'Add some AmazingFeature')
  4. Push to the branch (git push origin feature/AmazingFeature)
  5. Open a Pull Request

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

  • Inspired by Zenject's clean subcontainer API
  • Built on top of Autofac's powerful DI container
  • Thanks to all contributors who helped improve this project
Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 is compatible.  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 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. 
.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 is compatible. 
.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.

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
2.0.0 433 9/17/2025 2.0.0 is deprecated because it is no longer maintained.
1.0.0 295 8/19/2025 1.0.0 is deprecated because it is no longer maintained.

version 2.0
simplified reqirements for subcontainer resolve
added builders
move from installers to Autofac's modules