如何使用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();
}
}
答案 0 :(得分:9)
如果你正在构建单例或类似的东西并尝试注入依赖项,通常你会将代码编写为普通类,而不是试图输入大量(可能是不正确的)代码来管理单例而是注册对象InSingletonScope
(v2 - 你没有提到你的Ninject版本)。每次执行此操作时,您只有一个不会显示其依赖关系的类。
如果你感觉特别血腥,并且确定你想要反对这种一般流程,那么Ninject给你的主要工具是Kernel.Inject
,你可以在你(或其他人)之后使用它new
d实例注入依赖项。但是,为了找到一个内核,你通常会使用一个服务定位器,这可能会造成尽可能多的麻烦。
编辑:感谢您的跟进 - 我看到您的目标。这是一种近似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 );
}
}
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>();
}
}
...
我没有想到这一点,我并不是推荐这个好主意 - 可能有更好的方法来构建这样的东西。 @Mark Seemann? :P
我相信Unity和MEF也支持这方面的事情(关键词:自动工厂,Func)
编辑2:如果您愿意使用特定于容器的属性并删除属性注入,则语法较短(即使Ninject允许您覆盖特定属性,我更喜欢构造函数注入):
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
并注入(但这不能直接在静态方法中使用) )。