
DEPENDENCY INJECTION DEPENDENCY INJECTION INGEGNERIA DEL SOFTWARE Università degli Studi di Padova Dipartimento di Matematica Corso di Laurea in InFormatica Architetturali [email protected] Dependency injection, Model view controller Ingegneria del software Riccardo Cardin 2 INTRODUZIONE E CONTESTO PROBLEMA MovieLister nasconde le ¢ Scopo ¢ Esempio naive proprie dipendenze in un metodo. Separazione del comportamento di una componente dalla risoluzione delle sue dipendenze ¢ Motivazione Collegare due componenti in modo esplicito ne aumenta l’accoppiamento ¢ Progettazione unit-test difficoltosa ¢ Riutilizzo scarso della componente ¢ Scarsa manutenibilità Le dipendenze vanno minimizzate!!! Ingegneria del software Riccardo Cardin 3 Ingegneria del software Riccardo Cardin 4 PROBLEMA STRUTTURA ¢ Utilizzo di classi factory ¢ Inversion of Control Utilizza metodi statici nel recupero di istanze concrete Il ciclo di vita degli oggetti è gestito da una entità ad interfacce esterna (container) ¢ Si può fare di meglio... ¢ Tutti i framework moderni implementano IoC ¢ Dependency Injection con IoC Le dipendenze sono “iniettate” dal container La componente dichiara solo le sue dipendenze ¢ Minimizzazione del livello di accoppiamento Diversi tipi di injection ¢ Constructor injection ¢ Setter injection Ingegneria del software Riccardo Cardin 5 Ingegneria del software Riccardo Cardin 6 STRUTTURA SOLUZIONE ¢ Dependency Injection con IoC ¢ Constructor injection Assembler risolve le dipendenze delle componenti Dipendenze dichiarate come parametri del costruttore ¢ Il ciclo di vita degli oggetti è deciso dal container public class MovieLister { private MovieFinder finder; ¢ Configurazione: meta-linguaggio (XML) o programmatica public MovieLister(MovieFinder finder) { // Dichiarazioe dip. this.finder = finder; ¢ à Cambio di movie finder Cambio di configurazione } // ... } Vantaggi ¢ Permette di costruire oggetti validi sin dalla loro istanziazione ¢ Favorisce la costruzione di oggetti immutabili Svantaggi ¢ Telescoping ¢ A volte è difficile comprendere il significato dei parametri Ingegneria del software Riccardo Cardin 7 Ingegneria del software Riccardo Cardin 8 SOLUZIONE GOOGLE GUICE ¢ Setter injection ¢ Lightweight DI framework Dipendenze dichiarate come metodi setter Class injection (@Inject – JSR-330) public class MovieLister { Configurazione Java estendendo AbstractModule private MovieFinder finder; public void setFinder(MovieFinder finder) { public class MovieModule extends AbstractModule { this.finder = finder; @Override } // ... protected void configure() { } // Istruisce il container su come risolvere la dipendenza bind(MovieFinder.class).to(ColonMovieFinder.class); } Vantaggi } ¢ Individuazione precisa delle dipendenze e dei loro nomi public class MovieLister { ¢ Lavora meglio con le gerarchie di classi // L’annotazione istruisce il container di risolvere // automaticamente le dipendenze dichiarate Svantaggi @Inject public MovieLister(MovieFinder finder) { ¢ La componente è costruita per passi this.finder = finder; } // ... ¢ Non è abilitante all’immutabilità } Ingegneria del software Riccardo Cardin 9 Ingegneria del software Riccardo Cardin 10 GOOGLE GUICE GOOGLE GUICE ¢ Lightweight DI framework ¢ Lightweight DI framework Method (setter) injection Cointainer è una struttura Map<Class<?>, Object> public class MovieLister { // L’annotazione istruisce il container su come risolvere Non è possibile avere due oggetti dello stesso tipo // automaticamente le dipendenze dichiarate ¢ È possibile utilizzare qualificatori ulteriori per questo caso @Inject public setFinder(MovieFinder finder) { Si integra con AOP, Servlet spec., DAO, ... this.finder = finder; } // ... ¢ @Named, @Singleton, @SessionScoperd, @RequestScoped... } ¢ https://github.com/google/guice/wiki/BindingAnnotations Field injection public static void main(String[] args) { public class MovieLister { // Guice.createInjector() takes your Modules, and returns a new // Risolta automaticamente dall’injector. Piu’ conciso ma // Injector instance. Most applications will call this method // meno verificabile // exactly once, in their main() method. @Inject MovieFinder finder; Injector injector = Guice.createInjector(new MovieModule()); } // Now that we've got the injector, we can build objects. MovieLister lister = injector.getInstance(MovieLister.class); } Ingegneria del software Riccardo Cardin 11 Ingegneria del software Riccardo Cardin 12 SPRING SPRING “Spring is a «lightweight» inversion of control and aspect oriented ¢ Configurazione XML container framework” org.springframework.beans.factory.BeanFactory ¢ Lightweight ¢ Implementazione del pattern factory, costruisce e risolve le Non è intrusivo, gli oggetti sviluppati non dipendono da dipendenze classi del framework ¢ Framework/Container org.springframework.context.ApplicationContext La configurazione utilizza XML, o annotazioni, o Java ¢ Costruita sulla bean factory, fornisce ulteriori funzionalità ¢ Lo sviluppatore può concentrarsi sulla logica di business ¢ AOP, transazionalità, ... Cointainer è una struttura Map<String, Object> ApplicationContext ctx = ¢ Utilizza semplici POJO: Bean new ClassPathXmlApplicationContext( Supporta sia constructor, che setter injection "com/springinaction/springidol/filename.xml"); ¢ JEE replacement // ... MVC, Front controller, DI, AOP, JDBC Template, Security ... MovieLister ml = (MovieLister) ctx.getBean("movieLister"); Ingegneria del software Riccardo Cardin 13 Ingegneria del software Riccardo Cardin 14 SPRING SPRING ¢ Configurazione XML ¢ Configurazione XML Dependency injection attraverso proprietà Dependency injection attraverso costruttori ¢ Spring risolve automaticamente la scelta del costruttore ¢ Utilizzo metodi setter e getter <?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> <beans> <bean id="movieLister" class=“MovieLister"> <beans> <constructor-arg ref="movieFinder"/> <bean id="movieLister" class=“MovieLister"> </bean > <!-- La classe ha come proprieta’ finder... --> <bean id=“movieFinder" class="ColonMovieFinder"> <property name="finder" ref="movieFinder" /> <constructor-arg value=“movies.csv"/> </bean> </bean> <bean id=“movieFinder" class="ColonMovieFinder"> </beans> <property name="file" value="movies.csv“ /> </bean> </beans> Oppure factory methods, init,destroy methods... Ingegneria del software Riccardo Cardin 15 Ingegneria del software Riccardo Cardin 16 SPRING SPRING ¢ Configurazione Java ¢ Wiring utilizzando annotazioni @Configuration: dichiara una classe configurazione Permette una gestione migliore della configurazione @Bean: dichiara un bean in progetti grandi @Configuration Introduce una dipendenza da framework esterni public class MovieConfig { ¢ @Bean Constructor injection @Autowired public MovieLister lister(){ ¢ @Inject, annotazione JSR-330 return new MovieLister( finder() ); ¢ } @Resource, annotazione JSR-250 bean id <?xml version="1.0" encoding="UTF-8"?> @Bean <!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" public MovieFinder finder(){ "http://www.springframework.org/dtd/spring-beans-2.0.dtd"> return new ColonMovieFinder("movies.csv"); </beans> } <context:annotation-config/> } <context:component-scan base-package="org.example"/> ApplicationContext ctx = [...] new AnnotationConfigApplicationContext(MovieConfig.class); Ingegneria del software Riccardo Cardin 17 Ingegneria del software Riccardo Cardin 18 SPRING JAVASCRIPT ¢ Wiring utilizzando annotazioni ¢ Dependency injection in Javascript @Inject/@Autowired Container è una mappa [string, function] ¢ Ricerca per tipo il bean della proprietà e lo usa come id ¢ Linguaggio non tipizzato staticamente ¢ Si utilizza su costruttori, proprietà, ... ¢ Non ha interfacce esplicite ¢ Il bean non deve essere ambiguo ¢ Disambiguazione tramite @Named per l’ID @Inject JS è strutturato a moduli (module pattern) private Instrument instrument; ¢ Injection di oggetti o interi moduli @Inject @Named("guitar") // Fornisce nome differente dal tipo Esistono diverse librerie (API) per la DI private Instrument instrument2; ¢ RequireJS/AMD - http://requirejs.org/ ¢ Autodiscovery ¢ Inject.js - http://www.injectjs.com/ @Component, @Controller, @Service, ... ¢ AngularJS (framework) - https://angularjs.org/ Ingegneria del software Riccardo Cardin 19 Ingegneria del software Riccardo Cardin 20 ANGULARJS 1.6 ANGULARJS 1.6 ¢ Javascript framework ¢ Dependency Injection Client-side $provide: risolve le dipendenze fra le componenti Model-View-Whatever ¢ Viene invocato direttamente da Angular al bootstrap // Provide the wiring information in a module Ritorna il servizio ¢ MVC per alcuni aspetti (controller)… angular.module('myModule', []). $provide ¢ …MVVM per altri (two-way data binding) // Teach the injector how to build a 'greeter' // Notice that greeter itself is dependent on '$window' factory('greeter', function($window) { // This is a factory function, and is responsible for Utilizza HTML come linguaggio di templating // creating the 'greet' service. ¢ Non richiede operazioni di DOM refresh return { greet: function(text) { ¢ Controlla attivamente le azioni utente, eventi del browser $window.alert(text); "Ricetta" di come } }; costruire greeter Dependence injection }); ¢ Fornisce ottimi strumenti di test // Request any dependency from the $injector
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages8 Page
-
File Size-