Les nouveautés de ASP.NET Core 2.0 Preview 1 -
Partie 2 : Program.cs et CreateDefaultBuilder, par Hinault Romaric

Le , par Hinault Romaric, Responsable .NET
Dans la première partie de cette série de billets, nous avons installé la Preview de .NET Core 2.0. Nous avons créé une première application avec cette dernière. Par la suite, nous avons exploré le nouveau meta-package Microsoft.AspNetCore.All et .NET Core 2.0 Runtime Store.


Continuons à explorer les nouveautés de cette version. Observons maintenant le contenu du fichier Program.cs :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
public class Program 
    { 
        public static void Main(string[] args) 
        { 
            BuildWebHost(args).Run(); 
        } 
  
        public static IWebHost BuildWebHost(string[] args) => 
            WebHost.CreateDefaultBuilder(args) 
                .UseStartup<Startup>() 
                .Build(); 
    }


On se rend compte que le contenu de celui-ci a été simplifié. Dans la version précédente de la plateforme, le fichier Program.cs avait le contenu suivant :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
public static void Main(string[] args) 
        { 
            var host = new WebHostBuilder() 
                .UseKestrel() 
                .UseContentRoot(Directory.GetCurrentDirectory()) 
                .UseIISIntegration() 
                .UseStartup<Startup>() 
                .UseApplicationInsights() 
                .Build(); 
  
            host.Run(); 
        }


La portion de code qui attire l’attention et dont la syntaxe semble un peu superflue est la suivante :

Code c# : Sélectionner tout
1
2
3
4
 public static IWebHost BuildWebHost(string[] args) => 
            WebHost.CreateDefaultBuilder(args) 
                .UseStartup<Startup>() 
                .Build();

Dans la mesure où le corps de la fonction BuildWebHost ne devait contenir qu’une seule instruction avec le Return, les développeurs de ASP.NET Core ont utilisé une nouveauté de C# 6 appelée « expression-bodied members » (je préfère m’abstenir de fournir une traduction), qui utilise une flèche comme on le fait avec une expression lambda pour introduire le corps de la méthode. Sans l’utilisation de cette fonctionnalité, le code de cette méthode aurait ressemblé à ceci :

Code c# : Sélectionner tout
1
2
3
4
5
6
public static IWebHost BuildWebHost(string[] args)  
        { 
           return WebHost.CreateDefaultBuilder(args) 
                .UseStartup<Startup>() 
                .Build(); 
        }

Vous remarquerez également que lors de l’initialisation de l’hôte (Host), nous n’avons plus les lignes de code permettant de spécifier le serveur Web qui sera utilisé (UseKestrel()), ou encore de spécifier le répertoire racine de l’application (UseContentRoot(Directory.GetCurrentDirectory())).

À la place, nous avons la méthode CreateDefaultBuilder, qui permet de faire cela, en plus d’autres choses. Le code de la classe WebHost est disponible sur GitHub à l’adresse suivante, pour les plus curieux : https://github.com/aspnet/MetaPackag...ore/WebHost.cs

Ci-dessous le code de CreateDefaultBuilder :

Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public static IWebHostBuilder CreateDefaultBuilder(string[] args) 
        { 
            var builder = new WebHostBuilder() 
                .UseKestrel() 
                .UseContentRoot(Directory.GetCurrentDirectory()) 
                .ConfigureAppConfiguration((hostingContext, config) => 
                { 
                    var env = hostingContext.HostingEnvironment; 
 
                    config.AddJsonFile("appsettings.json", optional: true, reloadOnChange: true) 
                          .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true); 
 
                    if (env.IsDevelopment()) 
                    { 
                        var appAssembly = Assembly.Load(new AssemblyName(env.ApplicationName)); 
                        if (appAssembly != null) 
                        { 
                            config.AddUserSecrets(appAssembly, optional: true); 
                        } 
                    } 
 
                    config.AddEnvironmentVariables(); 
 
                    if (args != null) 
                    { 
                        config.AddCommandLine(args); 
                    } 
                }) 
                .ConfigureLogging((hostingContext, logging) => 
                { 
                    logging.AddConfiguration(hostingContext.Configuration.GetSection("Logging")); 
                    logging.AddConsole(); 
                    logging.AddDebug(); 
                }) 
                .UseIISIntegration() 
                .UseDefaultServiceProvider((context, options) => 
                { 
                    options.ValidateScopes = context.HostingEnvironment.IsDevelopment(); 
                }); 
 
            return builder; 
        }
Ce code permet de :

  1. Définir Kestrel comme serveur Web ;
  2. Définir le répertoire racine de l’application ;
  3. Charger les éléments de configuration qui sont définis dans le fichier appsettings.json (il est donc important de respecter cette convention). Cette étape était précédemment effectuée dans le fichier Startup.cs ;
  4. Procéder à la configuration de ILoggerFactory pour la journalisation de votre application (ce qui se faisait précédemment dans le fichier Startup.cs) ;
  5. Activer IISIntegration et bien plus.


Les développeurs de ASP.NET Core ont opté pour ce choix parce que la configuration d’une application ASP.NET Core est assez standard et ne varie pas beaucoup d’une application à une autre. Grâce à cette nouvelle implémentation fournie par CreateDefaultBuilder, le fichier Startup.cs devient :

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 public class Startup 
    { 
        // This method gets called by the runtime. Use this method to add services to the container. 
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940 
        public void ConfigureServices(IServiceCollection services) 
        { 
        } 
  
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
        public void Configure(IApplicationBuilder app, IHostingEnvironment env) 
        { 
            if (env.IsDevelopment()) 
            { 
                app.UseDeveloperExceptionPage(); 
            } 
  
            app.Run(async (context) => 
            { 
                await context.Response.WriteAsync("Hello World!"); 
            }); 
        } 
    }

Vous remarquerez par exemple la suppression des lignes de code permettant de charger le fichier de configuration, de prendre en compte les variables d’environnement, etc.

Code c# : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
public class Startup 
    { 
        public Startup(IHostingEnvironment env) 
        { 
            var builder = new ConfigurationBuilder() 
                .SetBasePath(env.ContentRootPath) 
                .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) 
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true) 
                .AddEnvironmentVariables(); 
            Configuration = builder.Build(); 
        } 
  
        public IConfigurationRoot Configuration { get; } 
  
        // This method gets called by the runtime. Use this method to add services to the container. 
        public void ConfigureServices(IServiceCollection services) 
        { 
            // Add framework services. 
            services.AddMvc(); 
        } 
  
        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. 
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) 
        { 
            loggerFactory.AddConsole(Configuration.GetSection("Logging")); 
            loggerFactory.AddDebug(); 
  
            if (env.IsDevelopment()) 
            { 
                app.UseDeveloperExceptionPage(); 
                app.UseBrowserLink(); 
            } 
            else 
            { 
                app.UseExceptionHandler("/Home/Error"); 
            } 
  
            app.UseStaticFiles(); 
  
            app.UseMvc(routes => 
            { 
                routes.MapRoute( 
                    name: "default", 
                    template: "{controller=Home}/{action=Index}/{id?}"); 
            }); 
        }

En déportant la configuration dans la méthode CreateDefaultBuilder, le code des fichiers Program.cs et Startup.cs est beaucoup plus simple. Dans la prochaine partie, nous découvrirons le nouveau Razor Pages.


Vous avez aimé cette actualité ? Alors partagez-la avec vos amis en cliquant sur les boutons ci-dessous :
Contacter le responsable de la rubrique Accueil