How do I handle classes with static methods with Ninject?

dependency-injection, ninject

Solution

If you're building a singleton or something of that nature and trying to inject dependencies, typically you instead write your code as a normal class, without trying to put in lots of (probably incorrect) code managing the singleton and instead register the object `InSingletonScope` (v2 - you didnt mention your Ninject version). Each time you do that, you have one less class that doesnt surface its dependencies.

If you're feeling especially bloody-minded and are certain that you want to go against that general flow, the main tools Ninject gives you is `Kernel.Inject`, which one can use after you (or someone else) has `new`d up an instance to inject the dependencies. But then to locate one's Kernelm you're typically going to be using a Service Locator, which is likely to cause as much of a mess as it is likely to solve.

EDIT: Thanks for following up - I see what you're after. Here's a hacky way to approximate the autofac automatic factory mechanism :-

/// <summary>
/// Ugly example of a not-very-automatic factory in Ninject
/// </summary>
class AutomaticFactoriesInNinject
{
    class Node
    {
    }

    class NodeFactory
    {
        public NodeFactory( Func<Node> createNode )
        {
            _createNode = createNode;
        }

        Func<Node> _createNode;
        public Node GenerateTree()
        {
            return _createNode();
        }
    }

    internal class Module : NinjectModule
    {
        public override void Load()
        {
            Bind<Func<Node>>().ToMethod( context => () => Kernel.Get<Node>() );
        }
    }

    [Fact]
    public void CanGenerate()
    {
        var kernel = new StandardKernel( new Module() );
        var result = kernel.Get<NodeFactory>().GenerateTree();
        Assert.IsType<Node>( result );
    }
}

The `ToMethod` stuff is a specific application of the `ToProvider` pattern -- here's how you'd do the same thing via that route:-

    ...

    class NodeProvider : IProvider
    {
        public Type Type
        {
            get { return typeof(Node); }
        }
        public object Create( IContext context )
        {
            return context.Kernel.Get<Node>();
        }
    }

    internal class Module : NinjectModule
    {
        public override void Load()
        {
            Bind<Func<Node>>().ToProvider<NodeProvider>();
        }
    }

    ...

I have not thought this through though and am not recommending this as A Good Idea - there may be far better ways of structuring something like this. @Mark Seemann? :P

I believe Unity and MEF also support things in this direction (keywords: automatic factory, Func)

EDIT 2: Shorter syntax if you're willing to use container-specific attributes and drop to property injection (even if Ninject allows you to override the specific attributes, I much prefer constructor injection):

    class NodeFactory
    {
        [Inject]
        public Func<Node> NodeFactory { private get; set; }
        public Node GenerateTree()
        {
            return NodeFactory();
        }
    }

EDIT 3: You also need to be aware of this Ninject Module by @Remo Gloor which is slated to be in the 2.4 release

EDIT 4: Also overlapping, but not directly relevant is the fact that in Ninject, you can request an `IKernel` in your ctor/properties and have that injected (but that doesn't work directly in a static method).

Problem

How do I handle classes with static methods with Ninject? That is, in C# one can not have static methods in an interface, and Ninject works on the basis of using interfaces? My use case is a class that I would like it to have a static method to create an unpopulated instance of itself. EDIT 1 Just to add an example in the TopologyImp class, in the GetRootNodes() method, how would I create some iNode classes to return? Would I construct these with normal code practice or would I somehow use Ninject? But if I use the container to create then haven't I given this library knowledge of the IOC then? ``` public interface ITopology { List<INode> GetRootNodes(); } public class TopologyImp : ITopology { public List<INode> GetRootNodes() { List<INode> result = new List<INode>(); // Need code here to create some instances, but how to without knowledge of the container? // e.g. want to create a few INode instances and add them to the list and then return the list } } public interface INode { // Parameters long Id { get; set; } string Name { get; set; } } class NodeImp : INode { public long Id { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } public string Name { get { throw new NotImplementedException(); } set { throw new NotImplementedException(); } } } // Just background to highlight the fact I'm using Ninject fine to inject ITopology public partial class Form1 : Form { private ITopology _top; public Form1() { IKernel kernal = new StandardKernel(new TopologyModule()); _top = kernal.Get<ITopology>(); InitializeComponent(); } } ```

Original source

Related problems