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

Я думаю, что использование некоторого метода, такого как aku's или Guy's , - это путь, но несколько вещей, которые нужно убрать из конкретных примеров:

  1. Основной предпосылкой было бы как можно скорее показать ваш всплеск на отдельном потоке. Это то, как я наклоняюсь, похоже на то, что иллюстрирует аку, так как это то, с чем я больше всего знаком. Я не знал о функции VB, о которой говорил Гай. И даже подумал, что это библиотека VB , он прав - это все ИЛ в конце. Таким образом, даже если он чувствует себя грязным , это не так уж плохо! :) Я думаю, вам нужно быть уверенным, что либо VB предоставляет отдельный поток для этого переопределения, либо тот, который вы сами создаете, - определенно исследуйте это.
  2. Предполагая, что вы создаете другой поток для отображения этого всплеска , вы захотите быть осторожным с обновлением пользовательских интерфейсов. Я рассказываю об этом, потому что вы упомянули о ходе обновления. В принципе, чтобы быть в безопасности, вам нужно вызвать функцию обновления (которую вы создаете) в форме всплеска с помощью делегата. Вы передаете этот делегат функции Invoke на вашем объекте формы заставки. Фактически, если вы вызываете брызговую форму непосредственно для обновления элементов прогресса / пользовательского интерфейса на ней, вы получите исключение, если вы работаете в среде .NET Net CLR. Как правило, любой элемент пользовательского интерфейса в форме должен обновляться потоком, который его создал, - это то, что обеспечивает Form.Invoke.

Наконец, я бы предпочел создать splash (если не использовать перегрузку VB) в основном методе вашего кода. Для меня это лучше, чем если бы основная форма выполняла создание объекта и была настолько тесно связана с ним. Если вы примете такой подход, я бы предложил создать простой интерфейс, который реализует экран заставки - что-то вроде IStartupProgressListener - который получает обновления прогона обновления через функцию-член. Это позволит вам легко переключаться в любом классе по мере необходимости и красиво отделять код. Форма всплеска также может знать, когда закрыть себя, если вы сообщите, когда пуск завершен.

14
задан Ruben Bartelink 26 April 2010 в 12:55
поделиться

1 ответ

Если вы создаете синглтон или что-то в этом роде и пытаетесь внедрить зависимости, обычно вы вместо этого пишете свой код как обычный класс, не пытаясь добавить много (возможно, неправильного) кода, управляющего синглтоном, и вместо этого регистрируете объект InSingletonScope (v2 - вы не упомянули свою версию Ninject). Каждый раз, когда вы это делаете, у вас появляется на один класс меньше, который не обнаруживает своих зависимостей.

Если вы чувствуете себя особенно одурманенным и уверены, что хотите пойти против этого общего потока, Ninject предлагает вам основные инструменты Kernel.Inject , которые можно использовать после вас (или кто-то другой) имеет новый d экземпляр для внедрения зависимостей. Но затем, чтобы определить местонахождение своего Kernelm, вы обычно будете использовать Service Locator, который, вероятно, вызовет столько же беспорядка, сколько и решит.

РЕДАКТИРОВАТЬ: Спасибо за продолжение - я вижу, что вам нужно. Вот хитрый способ приблизить автоматический заводской механизм autofac : -

/// <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: Вам также необходимо знать об этом модуле Ninject от @Remo Gloor, который должен быть в версии 2.4

РЕДАКТИРОВАТЬ 4: Также перекрывается, но не имеет прямого отношения, тот факт, что в Ninject вы можете запросить IKernel в своем ctor / properties и ввести его (но это не работает напрямую в статическом метод).

9
ответ дан 1 December 2019 в 15:21
поделиться
Другие вопросы по тегам:

Похожие вопросы: