Подтвердить что ты не робот

Как обрабатывать классы со статическими методами с помощью Ninject?

Как обрабатывать классы со статическими методами с помощью Ninject?

То есть, в С# нельзя иметь статические методы в интерфейсе, а 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();
    }
}
4b9b3361

Ответ 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 и ввести его (но это не работает непосредственно в статическом методе).