scala - Comparando Subcut y Scaldi
configuration dependency-injection (1)
Ambas bibliotecas pueden parecer bastante similares al juzgar la documentación introductoria, pero tienen grandes diferencias en la forma en que se implementan. Me gustaría advertirle que, como autor de uno de ellos (scaldi), probablemente no pueda hacer un juicio justo, por lo que debe tomar mis palabras con un grano de sal.
Módulo de composición y gráfica de dependencia.
Tienen un DSL muy similar para el enlace, la inyección y la forma en que traes Injector
/ BindingModule
en el alcance de la clase administrada (aunque el parámetro implícito).
Pero los contenedores de los enlaces tienen diferentes ideas detrás de ellos. Por ejemplo, en Subcut, una clase puede estar vinculada (ser una dependencia para otras clases) o inyectar dependencias en sí. Pero no ambos. Si desea inyectar algo en la clase que está vinculando actualmente, debe proporcionar explícitamente algún BindingModule
como argumento.Pero no puede hacerlo de forma genérica porque su (puede usar el módulo actual cuando está definiendo vinculaciones dentro de él, pero este módulo no tiene conocimiento de ninguna). tipo de composición, por lo que no he encontrado ninguna buena forma de implementar dependencias entre módulos como en este ejemplo: https://gist.github.com/OlegIlyenko/5623423 ) y normalmente no desea utilizar instancias concretas de otros módulos Scaldi asumir este problema es muy diferente. Cada enlace que se define en el BindingModule
actual (donde está definiendo la vinculación) está en construcción y aún no existeModule
es a la vez: puede inyectarse en otros enlaces y, a su vez, puede inyectar otras dependencias. Y el Injector
implícito siempre está disponible dentro de un módulo cuando está definiendo sus enlaces. Este inyector implícito representa no solo el módulo que está definiendo actualmente, sino que también conoce la composición final del módulo (si decide crearlo en algún momento). De modo que puede separar su aplicación en varios módulos, y los enlaces dentro de estos módulos pueden tener dependencias entre sí.
Personalmente creo que es la diferencia más grande e importante entre dos proyectos. Si aún no está seguro de lo que esto significa en la práctica, puedo recomendarle que pruebe ambos proyectos y se dará cuenta rápidamente de lo restrictivo que es Subcut a este respecto y lo flexible que es la solución de scaldi.
Flexibilidad
Scaldi es una biblioteca muy flexible, que te permite personalizar casi cualquier parte de ella. La mayor parte de esta flexibilidad se logró mediante el uso de clases de tipos. Por ejemplo, rasgo Identifier
. Subcut trabaja directamente con cadenas y clases cuando se trata de identificaciones para los enlaces. Así que el método de inject
toma String
como argumento y usted, como usuario, no puede cambiarlo. Scaldi, por otro lado, utiliza el rasgo de Identifier
lugar y en la mayoría de los lugares requiere no Identifier
, pero la evidencia de que CanBeIdentifier
clase de tipo CanBeIdentifier
para algún tipo en particular que quiera usar como identificador. De modo que usted, como usuario, puede personalizar lo que trata como identificador y cómo los identificadores se relacionan entre sí. La clase del enlace también es identificador, por lo que no hay casos especiales.
La misma idea se utiliza para la composición del módulo, que es muy flexible porque la composición real se realiza con la clase de tipos CanCompose
, lo que garantiza que siempre reciba el tipo de Injector
más concreto de la composición (esto es importante en el caso de inyectores inmutables. Si desea componer un inyector inmutable con otro inyector inmutable, recibirá el ImmutableInjectorAggregation
). Lo mismo se refleja en otras partes de la biblioteca, como las condiciones y el propio inyector (lo describí a continuación).
Enlaces condicionales
Los enlaces condicionales son ingenuamente compatibles con scaldi y es algo que no he visto en otras bibliotecas. Por lo tanto, puede definir declarativamente si su enlace está disponible o no, y cuándo. Lo encuentro muy útil en algunas situaciones como distinguir entre entornos (dev / test / prod). Los enlaces condicionales usan clases de tipo, por lo que también son muy flexibles.
Dinámica
Desde mi punto de vista, Scaldi es más dinámico que Subcutado principalmente debido a la forma en que se implementa Injector. Inyectado subcutáneo es sólo una colección de enlaces. En scaldi es una interfaz que tiene un método como getBinding
. Esto significa que no es necesario conocer todos los enlaces por adelantado. Por lo tanto, la integración con los marcos DI existentes como Spring o Guice y cosas como los archivos de propiedades (en realidad, Scaldi proporciona soporte de archivos de propiedades / propiedades del sistema con SystemPropertiesInjector
/ PropertiesInjector
, que puede componer con sus propios módulos).
Inmutabilidad
Scaldi hace una gran distinción entre módulos mutables e inmutables. Los módulos mutables tienen más funciones, pero también son más dinámicos y propensos a errores. Los módulos inmutables son más restrictivos, pero hacen que sea fácil razonar. Y generalmente tienes una opción. Por lo que sé, Subcut solo tiene un sabor donde puede definir sus enlaces dentro de un contexto mutable, pero después de que haya terminado de definirlos, es inmutable.
Probablemente hay muchas otras diferencias más pequeñas, pero espero haber podido resaltar las más importantes. Solo quiero recordarle una vez más, que solo tengo una buena idea de scaldi, por lo que algunos datos y observaciones sobre Subcut, que he descrito aquí, pueden ser inexactos o incluso no ser válidos.
Espero que esto ayude.
Estoy buscando a SubCut y Scaldi para usar en mis proyectos. Los ejemplos proporcionados en sus respectivos documentos de Primeros pasos parecen muy similares. Ninguno de los dos proyectos parece proporcionar documentación más allá de los documentos Getting Started y Scala.
Alguien podría resumir las diferencias prácticas entre estos marcos principalmente en términos de características y madurez / estabilidad. Estoy investigando estos paquetes porque necesito poder crear y componer la configuración dinámicamente en tiempo de ejecución. La configuración del tiempo de ejecución es la razón principal por la que estoy viendo estas bibliotecas en lugar de usar implícitos y / o el patrón de pastel de capa para realizar la configuración / DI, por lo que las instalaciones de configuración en tiempo de ejecución son las más importantes para mí. Además, no creo que los complementos del compilador sean una opción para mí, pero estas dos bibliotecas se pueden usar sin sus respectivos complementos con solo un pequeño aumento de verbosidad. Estoy en Scala-2.9.2 por el momento.
También me interesan las sugerencias para realizar la configuración / DI de tiempo de ejecución directamente en Scala, pero convertir todo mi proyecto al estilo monádico tampoco es una opción para mí.