Существует ли хороший/надлежащий способ решить проблему цикла внедрения зависимости в учебном руководстве по ASP.NET MVC ContactsManager?

Что не работает:

причина последняя команда Вы заключили в кавычки:

cmd 1>/dev/null 2>&1 | grep pattern

не работает, основы от беспорядка на порядке, в котором работает перенаправление. Вы ожидали, что последнее заключенное в кавычки перенаправление будет применено к тем перед ним на каждом выводе, так, чтобы произведенный исходный дескриптор файла стандартного вывода (1) перешел к/dev/null, и производить к дескриптору файла стандартной погрешности (2), перейдет к исходному стандартному выводу.

Однако это не то, как перенаправление оболочки работает. Каждое перенаправление заставляет дескрипторы файлов быть "повторно отображенными" путем закрытия "источника" и дублирования "места назначения" в него (см. man страницы dup(2) и close(2)), в порядке. Это означает, что в Вашем стандартном выводе команды сначала заменяется /dev/null, и затем стандартная погрешность, замененная стандартным выводом, который уже является /dev/null.

, Что работы:

Поэтому для получения желаемого эффекта просто необходимо инвертировать перенаправления. Затем у Вас будет стандартная погрешность, переходят к стандартному выводу, и исходный стандартный вывод переходит в /dev/null:

cmd 2>&1 >/dev/null | grep pattern

(отмечают, что 1 прежде > является ненужным - для стандартного вывода перенаправления вывода, значение по умолчанию)

Приложение : Charlie упомянул, что перенаправил к [1 111] для закрытия дескриптора файла. При использовании интерактивной оболочки, которая поддерживает то расширение (bash и некоторые другие реализации делают, но не все и это не стандартно ), можно также сделать это как это:

cmd 2>&1 >&- | grep pattern

Это может быть лучше - это может сэкономить некоторое время, потому что, когда команда пытается записать в стандартный вывод, вызов к [1 113] может сразу перестать работать, не ожидая контекстного переключения в ядро и драйвера, обрабатывающего /dev/null (в зависимости от реализации системного вызова - некоторые могут поймать это в эти libc функция, и у некоторых может также быть специальная обработка для [1 116]). Если существует большой вывод, который может стоить, и это быстрее для ввода.

Это будет главным образом работать, потому что большинство программ не заботится, не удается ли им записать в стандартный вывод (кто действительно проверяет возвращаемое значение [1 117]?) и не будет возражать, тот стандартный вывод закрывается. Но некоторые программы могут прыгнуть с парашютом с кодом неисправности если write сбои - обычно процессоры блока, программы, пользующиеся некоторой осторожной библиотекой для ввода-вывода или регистрирующиеся к выводу stdandard. Таким образом, если это не работает, помнят, что это - вероятная причина, и попробуйте /dev/null.

22
задан JohannesH 21 September 2009 в 06:56
поделиться

3 ответа

As a general consideration, circular dependencies indicate a design flaw - I think I can safely say this since you are not the original author of the code :)

I wouldn't consider an Initialize method a good solution. Unless you are dealing with an add-in scenario (which you aren't), Method Injection is not the right solution. You have almost already figured that out, since you find it unsatisfactory that you need to manually invoke it because your DI Container can't.

Unless I am entirely mistaken, the ContactController doesn't need the IValidationDictionary instance before its Action methods are being invoked?

If this is true, the easiest solution would probably be to define an IValidationDictionaryFactory interface and make the ContactController constructor take an instance of this interface.

This interface could be defined like this:

public interface IValidationDictionaryFactory
{
    IValidationDictionary Create(Controller controller);
}

Any Action method on the controller that needs an IValidationDictionary instance can then invoke the Create method to get the instance.

The default implementation would look something like this:

public class DefaultValidationDictionaryFactory : IValidationDictionaryFactory
{
    public IValidationDictionary Create(Controller controller)
    {
        return controller.ModelState;
    }
}
11
ответ дан 29 November 2019 в 05:51
поделиться

В общем случае циклические зависимости указывают недостаток дизайна - я думаю, что могу с уверенностью сказать это, поскольку вы не являетесь первоначальным автором кода:)

Я бы не стал считать метод Initialize хорошим решением. Если вы не имеете дело со сценарием надстройки (а это не так), внедрение метода не является правильным решением. Вы почти уже поняли это, поскольку считаете неудовлетворительным то, что вам нужно вызывать его вручную, потому что ваш контейнер DI не может.

Если я полностью не ошибаюсь, ContactController не нуждается в экземпляре IValidationDictionary перед его методами действия вызываются?

Если это правда, Внедрение состояния модели контроллеров в службу, а затем внедрение службы в контроллер просто невозможно с помощью внедрения конструктора. Нужно быть первым.

Может быть, есть способ использовать инъекцию свойств? Но я думаю, это тоже будет сложно.

1
ответ дан 29 November 2019 в 05:51
поделиться

Как насчет того, чтобы немного изменить / улучшить дизайн примерно так: http://forums.asp.net/t/1486130.aspx

2
ответ дан 29 November 2019 в 05:51
поделиться
Другие вопросы по тегам:

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