Введение Инжектора Зависимости с помощью Внедрения зависимости

Я не нашел подтверждение на этом, но я верю проверкам php, если идентификатор сессии уже существует прежде, чем создать один с тем идентификатором.

люди проблемы перехвата сеанса волнуются по поводу, когда кто-то узнает идентификатор сессии активного пользователя. Это может быть предотвращено во многих отношениях для большего количества информации, на которой Вы видите эта страница на php.net и данная статья на фиксации сессии

8
задан andreialecu 12 December 2009 в 00:50
поделиться

3 ответа

Althought несколько противоречивым: да, это анти-паттерн. Он известен как Service Locator , и хотя некоторые считают его правильным шаблоном проектирования, я считаю его анти-шаблоном.

Эта проблема заключается в том, что использование, например, вашего класса UserAccounts становится неявным ] вместо явного . Хотя конструктор заявляет, что ему нужен IDependencyResolver, он не указывает, что в нем должно быть. Если вы передадите ему IDependencyResolver, который не может разрешить ISomeType, он выбросит.

Что еще хуже, на более поздних итерациях у вас может возникнуть соблазн разрешить какой-то другой тип из UserAccounts. Он отлично скомпилируется, но, вероятно, сработает во время выполнения, если / когда тип не может быть разрешен.

Не идите по этому пути.

Исходя из предоставленной информации, невозможно точно сказать вам, как вы должны решить вашу конкретную проблема с круговыми зависимостями, но я бы посоветовал вам переосмыслить свой дизайн. Во многих случаях циклические ссылки являются признаком Leaky Abstractions , поэтому, возможно, если вы немного переделаете свой API, он исчезнет - часто удивительно, насколько небольшие изменения требуются.

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

  • Во многих случаях хорошо работает модель публикации / подписки .
  • Шаблон Посредник может предоставить альтернативу, если связь должна идти в обе стороны.
  • Вы также можете ввести Абстрактную фабрику для извлечения экземпляра, который вы по мере необходимости, вместо того, чтобы требовать немедленного подключения.
7
ответ дан 5 December 2019 в 17:38
поделиться

Я согласен с ForeverDebugging - было бы хорошо устранить циклическую зависимость. Посмотрите, можете ли вы разделить классы следующим образом:

  • Foo.Payment.dll: Классы, которые имеют дело только с платежами, а не с пользователями
  • Foo.Users.dll: Классы, которые имеют дело только с пользователями, а не с платежами
  • Foo.UserPayment.dll: Классы, которые имеют дело как с платежами, так и с пользователями

Затем у вас есть одна сборка, которая ссылается на две другие, но без круга зависимостей.

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

  • Foo.Users.UserAccounts зависит от Foo.Shared.IPaymentHistory, который реализуется Foo.Payment.PaymentHistory.
  • Другой класс оплаты, Foo.Payment.PaymentGateway, зависит от на Foo.Shared.IUserAccounts. IUserAccounts реализуется с помощью Foo.Users.UserAccounts.

Предположим, что нет других зависимостей.

Здесь есть круг сборок, которые будут зависеть друг от друга во время выполнения в вашем приложении (хотя они не зависят от каждого другие во время компиляции, поскольку они проходят через общую DLL). Но не существует круга классов, которые зависят друг от друга во время компиляции или выполнения.

В этом случае вы по-прежнему сможете использовать свой контейнер IoC в обычном режиме без добавления дополнительного уровня косвенности. В своем MyModule просто привяжите каждый интерфейс к соответствующему конкретному типу. Заставьте каждый класс принимать свои зависимости в качестве аргументов конструктору. Когда вашему коду приложения верхнего уровня требуется экземпляр класса, позвольте ему запросить этот класс у контейнера IoC. Позвольте контейнеру IoC позаботиться о том, чтобы найти все, от чего зависит класс.



Если вы все-таки получите циклическую зависимость между классами, вам, вероятно, потребуется использовать инъекцию свойств (также известную как внедрение установщика) в один из классов вместо внедрения конструктора . Я не использую Ninject, но он поддерживает внедрение свойств - вот документация .

Обычно контейнеры IoC используют внедрение конструктора - они передают зависимости конструктору класса, который от них зависит. Но это не работает, когда есть циклическая зависимость. Если классы A и B зависят друг от друга, вам нужно будет передать экземпляр класса A в конструктор класса B. Но для создания A вам необходимо передать экземпляр класса B в его конструктор. Это проблема курицы и яйца.

При внедрении свойств вы указываете своему контейнеру IoC сначала вызвать конструктор, а затем установить свойство для созданного объекта. Обычно это используется для необязательных зависимостей, таких как регистраторы. Но вы также можете использовать его для разрыва круговой зависимости между двумя классами, которые требуют друг друга.

Это некрасиво, а я '

2
ответ дан 5 December 2019 в 17:38
поделиться

Мне это кажется немного странным. Можно ли разделить логику, для которой требуются обе ссылки, в третью сборку, чтобы сломать зависимости и избежать риска?

1
ответ дан 5 December 2019 в 17:38
поделиться
Другие вопросы по тегам:

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