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