Ninject.Extension.AutoFactories 1.1.6

dotnet add package Ninject.Extension.AutoFactories --version 1.1.6                
NuGet\Install-Package Ninject.Extension.AutoFactories -Version 1.1.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="Ninject.Extension.AutoFactories" Version="1.1.6" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add Ninject.Extension.AutoFactories --version 1.1.6                
#r "nuget: Ninject.Extension.AutoFactories, 1.1.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.
// Install Ninject.Extension.AutoFactories as a Cake Addin
#addin nuget:?package=Ninject.Extension.AutoFactories&version=1.1.6

// Install Ninject.Extension.AutoFactories as a Cake Tool
#tool nuget:?package=Ninject.Extension.AutoFactories&version=1.1.6                

NuGet Version NuGet Downloads Issues

Ninject.Extensions.AutoFactories

This library is a Source Generator for Ninject that generates factory for types during the compilation process. This removes the need to have to write uninteresting boilerplate code.

Quick Example

This code below uses this library to auto generate the IShippingOrderFactory and it's Get method to create new instances of ShippingOrder with both user provider and DI provided parameters.

using Ninject;

namespace Operations 
{
    [GenerateFactory] // <-- Add attribute 
    public class ShippingOrder 
    {
        public ShippingOrder(
            // No attribute means it's user provided
            string orderId,
            // 'FromFactory' means it should be provided by DI
            [FromFactory] IShippingProvider provider)
        {}
    }

    public class Program 
    {

        public static void Main(string[] args)
        {
            IKernel kernel = new StandardKernel();

            // Generated extension method that binds all the factories to Ninject. 
            kernel.LoadFactories();

            // The class is generated `ShippingOrderFactory` along with a 
            // matching interface `IShippingOrderFactory`.
            IShippingOrderFactory factory = kernel.Get<IShippingOrderFactory>(); /

            // The generated method require user to provide all parameters not marked
            // with 'FromFactory' attribute.
            ShippingOrder shippingOrder = factory.Get("random_id")
        }
    }
}

Introduction

The best practice for using a Dependency Injection (DI) container in a software system is to restrict direct interaction with the container to the Composition Root.

However, many applications face the challenge of not being able to instantiate all dependencies at startup or at the beginning of each request, due to incomplete information at those times. These applications require a method to create new instances later using the Kernel. This should be done without referencing the container's types outside of the Composition Root. This is where factories come in.

Lets say we have this the following class:

public class Coffee
{
    private IMilkService m_milkService;

    public Coffee(IMilkService milkService)
    {
        m_milkService = milkService;
    }
}

If we wanted to have the ability to create new Coffee we would create a factory:

public class CoffeeFactory
{
    private IKernel m_kernel;

    public CoffeeFactory(IKernel kernel)
    {
        m_kernel = kernel;
    }

    public Foo Create()
        => m_kernel.Get<Foo>():
}

Having this factory means that the IMilkService would be resolved by the Kernel and we don't have to worry about passing it in.

If we wanted to add a user parameter like Size we could update the factory to reflect this.

using Ninject.Parameters;

public class Coffee
{
    public Size Size { get; }
    private IMilkService m_milkService;

    public Coffee(IMilkService milkService, Size size)
    {
        Size = size;
        m_milkService = milkService;
    }
}


public class CoffeeFactory
{
    private IKernel m_kernel;

    public CoffeeFactory(IKernel kernel)
    {
        m_kernel = kernel;
    }

    public Foo Create(Size size)
    {
        return m_kernel.Get<Foo>(new IParameter[] {
            new ConstructorParameter("size", size)
        }):
    }
}

There is a problem here and is the hard coded parameter size. With Ninject to provide external parameters you need the exact parameter, size. If someone were to go in in change size to coffeeSize this call would throw a runtime exception. This is what this library tries to do by making this a compile time error instead.

How It Works

To generate factories for your types you apply the [AutoFactory] attribute. A new factory will be generated for ever class that has this attribute. For every single constructor a Create{ClassName} method will be generated as well. Any parameters that don't have [FromFactory] attribute applied will be arguments of the generated Create methods. For example

[AutoFactory]
public class Coffee
{
    public Size Size { get; }
    public IMilkService Milk { get; }

    public Coffee(
        Size size,
        [FromFactory] IMilkService milkService)
    {}
}

Would generate:

internal partial class CoffeeFactory : ICoffeeFactory 
{
    private readonly IResolutionRoot m_resolutionRoot;

    public CoffeeFactory(IResolutionRoot resolutionRoot)
    {
        m_resolutionRoot = resolutionRoot;
    }

    public CreateCoffee(Size size)
    {
        IParamater[] parameters = new IParameter[] 
        {
            new ConstructorParameter(nameof(size), size)
        };
        return m_resolutionRoot.Get<Coffee>();
    }
}

All the factories are registered in the generate Ninject.FactoriesModule which you need to register to your IKernel. To do this use the extension method.

IKernel kernel = new StandardKernel();
kernel.LoadFactories();
ICoffeeFactory coffeeFactory = kernel.Get<ICoffeeFactory>();
There are no supported framework assets in this 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.1.6 116 7/29/2024
1.1.5 157 7/9/2024
1.1.4 72 7/6/2024
1.1.3 108 7/4/2024
1.1.2 75 7/4/2024
1.1.1 84 7/4/2024
1.1.0 78 7/3/2024
1.0.2 82 7/3/2024
1.0.1 82 6/26/2024
1.0.0 91 6/22/2024