也就是说,在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(); } }
如果你感觉特别血腥,并且确定你想反对一般的流程,Ninject给你的主要工具是Kernel.Inject,在你(或其他人)之后,你可以使用新的实例注入依赖项.但是,然后找到一个人的内核,你通常会使用一个服务定位器,这可能会导致一个混乱,因为它有可能解决.
编辑:感谢您的跟进 – 我看到你的追求.这是一个很奇怪的方式来逼近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并注入(但不能在静态方法中直接使用).