如何使用Ninject处理带静态方法的类?

Gre*_*reg 14 dependency-injection ninject

如何使用Ninject处理带静态方法的类?

也就是说,在C#中,一个接口中不能有静态方法,而Ninject在使用接口的基础上工作?

我的用例是一个类,我希望它有一个静态方法来创建一个未填充的自身实例.

编辑1

只是在TopologyImp类中添加一个示例,在GetRootNodes()方法中,如何创建一些要返回的iNode类?我会用正常的代码练习构建这些或者我会以某种方式使用Ninject吗?但是,如果我使用容器创建那么我没有给IOC这个库知识呢?

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();
    }
}
Run Code Online (Sandbox Code Playgroud)

Rub*_*ink 9

如果您正在构建单例或类似的东西并尝试注入依赖项,通常您会将代码编写为普通类,而不是尝试输入大量(可能是不正确的)代码来管理单例而是注册对象InSingletonScope( v2 - 你没有提到你的Ninject版本).每次执行此操作时,您只有一个不会显示其依赖关系的类.

如果你感觉特别血腥,并且确定你想要反对这种一般流程,那么Ninject给你的主要工具是Kernel.Inject,在你(或其他人)new为实例注入依赖关系之后可以使用的工具.但是,为了找到一个人的内核,你通常会使用一个服务定位器,这可能会造成尽可能多的麻烦.

编辑:感谢您的跟进 - 我看到您的追求.这是一种近似autofac自动工厂机制的hacky方法: -

/// <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 );
    }
}
Run Code Online (Sandbox Code Playgroud)

这些ToMethod东西是模式的特定应用ToProvider- 这是你如何通过这条路线做同样的事情: -

    ...

    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>();
        }
    }

    ...
Run Code Online (Sandbox Code Playgroud)

我并没有想到这一点,我不建议这是一个好主意 - 可能有更好的方法来构建这样的东西.@Mark Seemann?:P

我相信Unity和MEF也支持这方面的事情(关键词:自动工厂,Func)

编辑2:如果您愿意使用特定于容器的属性并删除属性注入,则语法较短(即使Ninject允许您覆盖特定属性,我更喜欢构造函数注入):

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

编辑3:您还需要了解@Remo Gloor这个Ninject模块,该模块将在2.4版本中发布

编辑4:重叠,但不直接相关的事实是,在Ninject中,你可以请求IKernel你的ctor/properties并注入(但这不能直接在静态方法中工作).