Ответ 1
Если вы создаете синглтон или что-то в этом роде и пытаетесь ввести зависимости, обычно вы вместо этого пишете свой код как обычный класс, не пытаясь добавить много (возможно, неправильного) кода, управляющего синглоном, и вместо этого зарегистрировать объект InSingletonScope
(v2 - вы не указали свою версию Ninject). Каждый раз, когда вы это делаете, у вас есть еще один класс, который не влияет на его зависимости.
Если вы чувствуете себя особенно кровавым и уверены, что хотите идти против этого общего потока, основные инструменты Ninject дают вам Kernel.Inject
, который можно использовать после того, как вы (или кто-то еще) new
d экземпляр для ввода зависимостей. Но затем, чтобы найти один Kernelm, вы, как правило, будете использовать локатор сервисов, который, вероятно, вызовет такой беспорядок, который он может решить.
EDIT: Спасибо, что посмотрели - я вижу, что вам нужно. Вот хакерский способ приблизить автоматический автомат factory: -
/// <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 также поддерживают вещи в этом направлении (ключевые слова: автоматический factory, Func)
EDIT 2: более короткий синтаксис, если вы хотите использовать атрибуты, специфичные для контейнера, и отказаться от внедрения свойств (даже если Ninject позволяет переопределить определенные атрибуты, я предпочитаю вложение конструктора):
class NodeFactory
{
[Inject]
public Func<Node> NodeFactory { private get; set; }
public Node GenerateTree()
{
return NodeFactory();
}
}
РЕДАКТИРОВАТЬ 3: вам также нужно знать этот модуль Ninject от @Remo Gloor, который, как предполагается, будет в версии 2.4
EDIT 4: Также перекрытие, но не прямо релевантное, - это тот факт, что в Ninject вы можете запросить IKernel
в своих ctor/properties и ввести его (но это не работает непосредственно в статическом методе).