Ответ 1
Обе библиотеки могут выглядеть довольно схожими, судя по вводной документации, но они имеют большие различия в том, как они реализованы. Я хотел бы предупредить вас, что, будучи автором одного из них (scaldi), я, вероятно, не могу принять справедливое решение, поэтому вам нужно взять мои слова с солью.
Состав модуля и график зависимостей
У них очень похожий DSL для привязки, инъекции и способ, которым вы привносите Injector
/BindingModule
в область управляемого класса (хотя и неявный параметр).
Но у контейнеров привязок есть разные идеи. Например, в Subcut класс может быть либо привязан (быть зависимостью для других классов), либо вводить сами зависимости. Но не оба. Если вы хотите ввести что-то в классе, которое вы в настоящее время связываете, тогда вам нужно явно указать некоторый (Фактически вы можете использовать текущий модуль, когда вы определяете привязки внутри него, но это модуль не знает о каком-либо составе, поэтому я не нашел хорошего способа реализации кросс-модульных зависимостей, как в этом примере: https://gist.github.com/OlegIlyenko/5623423), и вы обычно не хотите использовать конкретные экземпляры других модулей. Scaldi взять на себя эту проблему совсем другое. Каждая привязка, которая определена в BindingModule
в качестве аргумента. Но вы не можете сделать это в общем, потому что ваш текущий BindingModule
(где вы определяете привязку) находится в стадии разработки и еще не существуетModule
, является следующим: может быть введена в другие привязки и сама может вводить другие зависимости. И неявный Injector
всегда доступен в модуле, когда вы определяете свои привязки. Этот неявный инжектор представляет собой не только модуль, который вы в настоящее время определяете, но также знает окончательный состав модуля (если вы решите его создать в какой-то момент). Таким образом, вы можете отделить свое приложение от нескольких модулей, а привязки в этих модулях могут иметь зависимости между собой.
Я лично считаю, что это самая большая и самая важная разница между двумя проектами. Если вы все еще не уверены в том, что это на самом деле означает, то я могу порекомендовать вам попробовать оба проекта, и вы быстро заметите, насколько ограничительный Subcut в этом отношении, и насколько гибкое решение scaldi.
Гибкость
Scaldi - очень гибкая библиотека, которая позволяет вам настраивать практически любую ее часть. Большая часть этой гибкости достигается за счет использования классов типов. Например, Identifier
. Subcut работает непосредственно со строками и классами, когда дело доходит до идентификации привязок. Поэтому метод inject
принимает String
как аргумент, и вы, как пользователь, не можете его изменить. С другой стороны, Scaldi использует черту Identifier
, а в большинстве мест не требуется Identifier
, но доказательство того, что класс типа CanBeIdentifier
существует для определенного типа, который вы хотите использовать в качестве идентификатора. Таким образом, вы, как пользователь, можете настраивать то, что вы рассматриваете как идентификатор, и как идентификаторы соотносятся друг с другом. Класс привязки также является идентификатором, поэтому особых случаев нет.
Такая же идея используется для модульной композиции, которая очень гибкая, потому что фактический состав выполнен с классом типа CanCompose
, который гарантирует, что вы всегда получаете наиболее конкретный тип Injector
из состава (это важно в случай неизменяемых инжекторов. Поэтому, если вы хотите создать неизменяемый инжектор с помощью другого неизменяемого инжектора, вы получите от него ImmutableInjectorAggregation
). То же самое отражается и в других частях библиотеки, таких как условия и инжектор (я описал это ниже).
Условные привязки
Условные привязки наивно поддерживаются scaldi, и это то, чего я не видел в других библиотеках. Таким образом, вы можете декларативно определить, доступно ли ваше связывание или нет, и когда. Я считаю, что это очень полезно в некоторых ситуациях, таких как различение сред (dev/test/prod). Условные привязки используют классы типов, поэтому они также очень гибкие.
Динамический
С моей точки зрения, Scaldi более динамичен, чем Subcut, главным образом из-за того, как внедрен инжектор. В инжекторе Subcut это всего лишь набор привязок. В scaldi это интерфейс, который имеет метод вроде getBinding
. Это означает, что ему не нужно знать все привязки заранее. Таким образом, интеграция с существующими инфраструктурами DI, такими как Spring или Guice, и такими вещами, как файлы свойств, очень просто (на самом деле Scaldi предоставляет системные свойства/поддержку свойств файлов из коробки с помощью SystemPropertiesInjector
/PropertiesInjector
, которые вы можете создавать с помощью собственных модули).
Неизменность
Scaldi делает большое различие между изменяемыми и неизменяемыми модулями. Mutable модули имеют больше возможностей, но также более динамичны и подвержены ошибкам. Неизменяемые модули более ограничительны, но позволяют легко рассуждать. И у вас обычно есть выбор. Насколько я знаю, Subcut имеет только один аромат, где вы можете определить свои привязки в изменяемом контексте, но после того, как вы закончите определять их, он будет неизменным.
Есть, вероятно, много других меньших различий, но я надеюсь, что смог выделить наиболее важные. Просто хочу напомнить вам еще раз, что у меня есть только хорошее представление о scaldi, поэтому некоторые факты и наблюдения о Subcut, которые я описал здесь, могут быть неточными или даже недействительными.
Надеюсь, что это поможет.