dependency-injection - 如何使用 Ninject 处理具有静态方法的类?

标签 dependency-injection ninject

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

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

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

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

最佳答案

如果您正在构建单例或类似性质的东西并尝试注入(inject)依赖项,通常您将代码编写为普通类,而不是尝试放入大量(可能不正确的)代码来管理单例,而是注册对象 InSingletonScope (v2 - 你没有提到你的 Ninject 版本)。每次你这样做时,你就会少一个类不会暴露它的依赖关系。

如果你感觉特别血腥,并且确定你想违背一般流程,那么 Ninject 给你的主要工具是 Kernel.Inject ,在你(或其他人)有 new d 一个实例来注入(inject)之后可以使用它依赖项。但是为了定位一个内核,您通常会使用服务定位器,这可能会造成尽可能多的困惑,因为它可能会解决。

编辑:感谢您的跟进-我知道您在追求什么。这是一种近似 the autofac automatic factory mechanism 的 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 );
    }
}
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>();
        }
    }

    ...

不过,我还没有考虑过这一点,也不建议将其作为一个好主意——可能有更好的方法来构建这样的东西。 @马克西曼? :P

我相信 Unity 和 MEF 也支持这个方向的东西(关键词:自动工厂,Func)

编辑 2:如果您愿意使用特定于容器的属性并使用属性注入(inject),则语法更短(即使 Ninject 允许您覆盖特定属性,我更喜欢构造函数注入(inject)):
    class NodeFactory
    {
        [Inject]
        public Func<Node> NodeFactory { private get; set; }
        public Node GenerateTree()
        {
            return NodeFactory();
        }
    }

编辑 3:您还需要注意 this Ninject Module by @Remo Gloor which is slated to be in the 2.4 release

编辑 4:同样重叠但不直接相关的事实是,在 Ninject 中,您可以在您的 ctor/properties 中请求一个 IKernel 并将其注入(inject)(但这不能直接在静态方法中工作)。

关于dependency-injection - 如何使用 Ninject 处理具有静态方法的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2710718/

相关文章:

c# - C#-使用依赖项注入(inject)(ninject)代替工厂模式

c# - 使用 Ninject 将通用接口(interface)绑定(bind)到存储库时获取 "MissingMethodException: Cannot create an instance of an interface"

python - 有没有像 python 的通用依赖解析库这样的东西?

oop - 在保持服务使用明确的同时减少构造函数参数?

asp.net - 我没有使用依赖注入(inject),但我得到 "An error occurred when trying to create a controller of type"

asp.net-mvc - Ninject 绑定(bind)可以基于 URL/路由值吗?

java - 使用 @Produces 注释时出现不明确的依赖关系

c# - Unity 和 TransientLifetimeManager

c# - Seemann 依赖注入(inject), "Three Calls Pattern"与服务定位器反模式

c# - 在两个服务中使用 ninject 都会在 C# 中创建循环依赖