O slideshow foi denunciado.

Dependency injection questa sconosciuta

1

Compartilhar

Carregando em…3
×
1 de 30
1 de 30

Dependency injection questa sconosciuta

1

Compartilhar

Baixar para ler offline

L'uscita di ASP.NET Core ha portato a una maggiore diffusione dell'utilizzo della DI (Dependency Injection) ma spesso senza che lo sviluppatore sappia la sua reale utilità o potenzialità.

Dependency Injection, uno dei design pattern della programmazione OOP. Una best-practice dello sviluppo che può portare alla semplificazione del codice scritto, facilitare il disacoppiamento, e migliorare la testabilità.
In questa sessione vedremo cos'è la DI e come utilizzarla intelligentemente all'interno dei nostri progetti.

Slide dell'evento "XE One Day - Good code" tenuto il 15.09.2018.
Il codice è disponibile alla pagina dell'evento https://www.xedotnet.org/eventi/one-day-good-code/

L'uscita di ASP.NET Core ha portato a una maggiore diffusione dell'utilizzo della DI (Dependency Injection) ma spesso senza che lo sviluppatore sappia la sua reale utilità o potenzialità.

Dependency Injection, uno dei design pattern della programmazione OOP. Una best-practice dello sviluppo che può portare alla semplificazione del codice scritto, facilitare il disacoppiamento, e migliorare la testabilità.
In questa sessione vedremo cos'è la DI e come utilizzarla intelligentemente all'interno dei nostri progetti.

Slide dell'evento "XE One Day - Good code" tenuto il 15.09.2018.
Il codice è disponibile alla pagina dell'evento https://www.xedotnet.org/eventi/one-day-good-code/

Mais Conteúdo rRelacionado

Audiolivros relacionados

Gratuito durante 30 dias do Scribd

Ver tudo

Dependency injection questa sconosciuta

  1. 1. www.xedotnet.org Andrea Dottor @dottor Dependency Injection questa sconosciuta
  2. 2. Dependency injection (DI) è un design pattern della programmazione orientata agli oggetti il cui scopo è quello di semplificare lo sviluppo e migliorare la testabilità di software di grandi dimensioni. Per utilizzare tale design pattern è sufficiente dichiarare le dipendenze che un componente necessita (dette anche interface contracts). Quando il componente verrà istanziato, un iniettore si prenderà carico di risolvere le dipendenze (attuando dunque l'inversione del controllo). Se è la prima volta che si tenta di risolvere una dipendenza l'injector istanzierà il componente dipendente, lo salverà in un contenitore di istanze e lo restituirà. Se non è la prima volta, allora restituirà la copia salvata nel contenitore. Una volta risolte tutte le dipendenze, il controllo può tornare al componente applicativo. Il pattern Dependency Injection coinvolge almeno tre elementi: • una componente dipendente, • la dichiarazione delle dipendenze del componente, definite come interface contracts, • un injector (chiamato anche provider o container) che crea, a richiesta, le istanze delle classi che implementano delle dependency interfaces. 15/09/2018 2 Dependency injection pattern (fonte: https://en.wikipedia.org/wiki/Dependency_injection)
  3. 3. Dependency injection (DI) è un design pattern della programmazione orientata agli oggetti il cui scopo è quello di semplificare lo sviluppo e migliorare la testabilità di software di grandi dimensioni. Per utilizzare tale design pattern è sufficiente dichiarare le dipendenze che un componente necessita (dette anche interface contracts). Quando il componente verrà istanziato, un iniettore si prenderà carico di risolvere le dipendenze (attuando dunque l'inversione del controllo). Se è la prima volta che si tenta di risolvere una dipendenza l'injector istanzierà il componente dipendente, lo salverà in un contenitore di istanze e lo restituirà. Se non è la prima volta, allora restituirà la copia salvata nel contenitore. Una volta risolte tutte le dipendenze, il controllo può tornare al componente applicativo. Il pattern Dependency Injection coinvolge almeno tre elementi: • una componente dipendente, • la dichiarazione delle dipendenze del componente, definite come interface contracts, • un injector (chiamato anche provider o container) che crea, a richiesta, le istanze delle classi che implementano delle dependency interfaces. 15/09/2018 3 Dependency injection pattern (fonte: https://en.wikipedia.org/wiki/Dependency_injection)
  4. 4. • https://deviq.com/inversion-of-control/ • Inversion of Control (IoC or IOC) describes a system that follows the Hollywood Principle ( “Don’t Call Us, We’ll Call You.” ). That is, flow of control within the application is not controlled by the application itself, but rather by the underlying framework. Typically in such an architecture, the application is written such that it ties into the application framework by handling framework events or plugging in to framework extension points. • An IOC Container, also known as a Dependency Inversion (DI) container, is a specialized factory used to facilitate dependency injection. 15/09/2018 4 Inversion of Control
  5. 5. public class HomeController : Controller { private readonly SqlDataAccess _dataAccess; public HomeController() { var connectionString = ConfigurationManager.ConnectionStrings["xe"].ConnectionString; this._dataAccess = new SqlDataAccess(connectionString); } public IActionResult Index() { var speakers = this._dataAccess.GetSpeakers(); return View(speakers); } } 15/09/2018 5 Prima
  6. 6. public class HomeController : Controller { private readonly IDataAccess _dataAccess; public HomeController(IDataAccess dataAccess) { this._dataAccess = dataAccess; } public IActionResult Index() { var speakers = this._dataAccess.GetSpeakers(); return View(speakers); } } 15/09/2018 6 Dopo
  7. 7. Riduzione delle dipendenze (dirette) il codice non è legato ad una precisa implementazione di una sua dipendenza, ma (solitamente) ad un'interfaccia, favorendo così il disaccoppiamento Codice più riutilizzabile riducendo le dipendenze si facilita il riuso del codice in contesti diversi Codice più testabile dipendendo da un'interfaccia, si è facilitati nella scrittura di test, potendo iniettare dei mock/stub/fake delle dipendenze Codice più leggibile si viene portati a scrivere classi focalizzate a risolvere il singolo problema, semplificando di molto la scrittura e la lettura del codice 15/09/2018 7 Dependency Injection Benefits
  8. 8. ASP.NET Core nasce con un proprio engine di Dependency Injection Utilizzato per iniettare tutti i service/factory necessari al funzionamento di ASP.NET Core ed Entity Framework Core Non si tratta di un'implementazione evoluta, ma espone funzionalità che sono sufficienti alla maggioranza delle applicazioni 15/09/2018 8 ASP.NET Core Dependency Injection
  9. 9. Service Type Lifetime Microsoft.AspNetCore.Hosting.Builder.IApplicationBuilderFactory Transient Microsoft.AspNetCore.Hosting.IApplicationLifetime Singleton Microsoft.AspNetCore.Hosting.IHostingEnvironment Singleton Microsoft.AspNetCore.Hosting.IStartup Singleton Microsoft.AspNetCore.Hosting.IStartupFilter Transient Microsoft.AspNetCore.Hosting.Server.IServer Singleton Microsoft.AspNetCore.Http.IHttpContextFactory Transient Microsoft.Extensions.Logging.ILogger<T> Singleton Microsoft.Extensions.Logging.ILoggerFactory Singleton Microsoft.Extensions.ObjectPool.ObjectPoolProvider Singleton Microsoft.Extensions.Options.IConfigureOptions<T> Transient Microsoft.Extensions.Options.IOptions<T> Singleton System.Diagnostics.DiagnosticSource Singleton System.Diagnostics.DiagnosticListener Singleton 15/09/2018 9 ASP.NET Core Framework-provided services
  10. 10. Le dipendenze/servizi possono venire create (e distrutte) in base a regole definite nel DI Container. Il DI Container si occupa di tenere traccia e risolvere le dipendenze. • Se un servizio ha a sua volta delle dipendenze, queste vengono gestite a loro volta dal DI container. • Se un servizio implementa IDisposable, il metodo Dispose verrà chiamato automaticamente. 15/09/2018 10 Service Life Times
  11. 11. Transient La dipendenza viene creata ogni volta che viene richiesta 15/09/2018 11 Service Life Times - Transient
  12. 12. Scoped La dipendenza viene create per "scope". In un'applicazione web lo scope è la singola richiesta http. 15/09/2018 12 Service Life Times - Scoped
  13. 13. Singleton La dipendenza viene creata la prima volta che viene richiesta. Tutte le volte successive viene ritornata sempre (e solo) l'istanza già creata. 15/09/2018 13 Service Life Times - Singleton
  14. 14. Le dipendenze vengono iniettate tramite il costruttore della classe/controller/handler/… 15/09/2018 14 Constructor Injection public class IndexModel : PageModel { private readonly IMyDependency _myDependency; public IndexModel(IMyDependency myDependency) { _myDependency = myDependency; } public async Task OnGetAsync() { await _myDependency.WriteMessage("IndexModel.OnGetAsync created this message."); } }
  15. 15. Utilizzando l'attributo [FromService] prima di un argomento di un metodo, fa si che questo venga recuperato dal DI Container Utile quando il servizio/dipendenza viene utilizzato da un solo metodo del controller e si vuole evitare di farlo risolvere ad ogni richiesta tramite dipendeza nel costruttore 15/09/2018 15 Action Injection with FromServices public IActionResult About([FromServices] IDateTime dateTime) { ViewData["Message"] = "Currently on the server the time is " + dateTime.Now; return View(); }
  16. 16. In ASP.NET Core la DI funziona anche a livello di View, dando la possibilità di iniettare direttamente le dipendenze tramite la keyword @inject 15/09/2018 16 DI nelle View @using System.Threading.Tasks @using ViewInjectSample.Model @using ViewInjectSample.Model.Services @model IEnumerable<ToDoItem> @inject StatisticsService StatsService <div> <p>Total Items: @StatsService.GetCount()</p> <p>Completed: @StatsService.GetCompletedCount()</p> <p>Avg. Priority: @StatsService.GetAveragePriority()</p> </div>
  17. 17. Possibilità di iniettare le dipendenze tramite proprietà delle classi Viene considerata come pratica da evitare in quanto causa una problematica "Temporal Coupling" • http://blog.ploeh.dk/2011/05/24/DesignSmellTemporalCoupling/ ASP.NET Core non supporta direttamente la property injection, ma è possibile utilizzarla sfruttando altri DI Container. 15/09/2018 17 Property Injection public class ValuesController : Controller { public IFooService FooService { get; set; } [HttpGet] public IActionResult Get() { // use FooService here } }
  18. 18. DEMO
  19. 19. Esistono già delle implementazioni di terze parte che possono andare a sostituire quella di default di ASP.NET Core: • Autofac • DryIoc • Grace • LightInject • StructureMap • Stashbox • Unity Utilizzo di altri DI container con Microsoft.Extensions.DependencyInjection 15/09/2018 19
  20. 20. The Unity Container (Unity) is a lightweight, extensible dependency injection container with optional support for instance and type interception. • https://github.com/unitycontainer/unity/ Registrazione delle dipendenze Recupero di una dipendenza Definizione di dipendenze nel file di configurazione 15/09/2018 20 Unity Container (Unity) var container = new UnityContainer(); container.RegisterType<IDataAccess, SQLDataAccess>(); IDBAccess data = container.Resolve<IDataAccess>(); var container = new UnityContainer(); var section =(UnityConfigurationSection)ConfigurationManager.GetSection("unity"); section.Containers.Default.Configure(container);
  21. 21. Autofac is an addictive Inversion of Control container for .NET Core, ASP.NET Core, .NET 4.5.1+, Universal Windows apps, and more. • https://autofac.org/ 15/09/2018 21 Autofac var builder = new ContainerBuilder(); // Register individual components builder.RegisterInstance(new TaskRepository()).As<ITaskRepository>(); builder.RegisterType<TaskController>(); builder.Register(c => new LogManager(DateTime.Now)).As<ILogger>(); // Scan an assembly for components builder.RegisterAssemblyTypes(myAssembly) .Where(t => t.Name.EndsWith("Repository")) .AsImplementedInterfaces(); var container = builder.Build();
  22. 22. DEMO
  23. 23. A partire dal .NET Framework 4.7.2 viene facilitato l'utilizzo della Dependency Injection, anche se non al livello di ASP.NET MVC • Annuncio del 30 Aprile 2018 - [ASP.NET] Support for ASP.NET Dependency Injection • "Support setter-based, interface-based and constructor-based injection in web application project in Handler, Module, Page, User control and Custom control." • "Support setter-based and interface-based injection in web site project in Handler, Module, Page, User controls and Custom controls." • "Extensebility to support different dependency injection frameworks." • Step1 - Implementare IServiceProvider • Step2 - Valorizzare HttpRuntime.WebObjectActivator nel Global.asax 15/09/2018 23 Utilizzare la DI in applicazioni WebForms
  24. 24. Su nuget è presente un package per avere la DI utilizzando Unity senza doversi occupare di implementare manualmente IServiveProvider Install-Package Microsoft.AspNet.WebFormsDependencyInjection.Unity 15/09/2018 24 Microsoft.AspNet.WebFormsDependencyInjection.Unity public class Global : System.Web.HttpApplication { protected void Application_Start(object sender, EventArgs e) { var container = this.AddUnity(); container.RegisterType<IPopularMovie, MovieManager>(); container.RegisterType<IMovieRepository, XmlMovieRepository>(); } }
  25. 25. Si può utilizzare la DI anche in applicazioni che utilizzando una versione del .NET Framework precedente alla versione 4.7.2 Per iniettare le dipendenze si può creare (o utilizzare) degli HttpModules, oppure una custom Factory che si occupi di gestire le estensioni aspx Si può utilizzare il pattern Service Locator per farsi dare manualmente le dipendenze 15/09/2018 26 Utilizzare la DI in applicazioni WebForms
  26. 26. DEMO
  27. 27. 15/09/2018 28 Quando non è consigliato utilizzare DI
  28. 28. • Dependency injection in ASP.NET Core • ASP.NET Core Dependency Injection Best Practices, Tips & Tricks • Dependency Injection Benefits • Use Dependency Injection In WebForms Application • Using ASP.Net Webform Dependency Injection with .NET 4.7.2 • Announcing the .NET Framework 4.7.2 Links 15/09/2018 29
  29. 29. 15/09/2018 30 Thanks
  30. 30. 15/09/2018 31 www.dottor.net andrea@dottor.net @dottor Andrea Dottor Microsoft MVP Developer Technologies Contatti

×