Ninject.Extension.AutoFactories
1.1.5
See the version list below for details.
dotnet add package Ninject.Extension.AutoFactories --version 1.1.5
NuGet\Install-Package Ninject.Extension.AutoFactories -Version 1.1.5
<PackageReference Include="Ninject.Extension.AutoFactories" Version="1.1.5" />
paket add Ninject.Extension.AutoFactories --version 1.1.5
#r "nuget: Ninject.Extension.AutoFactories, 1.1.5"
// Install Ninject.Extension.AutoFactories as a Cake Addin #addin nuget:?package=Ninject.Extension.AutoFactories&version=1.1.5 // Install Ninject.Extension.AutoFactories as a Cake Tool #tool nuget:?package=Ninject.Extension.AutoFactories&version=1.1.5
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>();
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.