46
ASP.Net 5 and C# 6 8 October 2015

ASP.Net 5 and C# 6

Embed Size (px)

Citation preview

Page 1: ASP.Net 5 and C# 6

ASP.Net 5

and C# 6

8October

2015

Page 2: ASP.Net 5 and C# 6

What’s this got to do with Umbraco?• In the short-term… not much!

• It’ll be a while before Umbraco itself runs on ASP.Net 5

• But for .Net developers there is a big change coming – of the scale we’ve had before:• “Classic” ASP…• … ASP.Net Web Forms…• … ASP.Net MVC…• ASP.Net 5

• Arguably, working with Umbraco, we are behind the .Net curve – so it’s important not to get left behind

Page 3: ASP.Net 5 and C# 6
Page 4: ASP.Net 5 and C# 6

Contents

1

2

3

ASP.Net 5

C# 6

Discussion time

Page 5: ASP.Net 5 and C# 6

ASP.Net 5

Page 6: ASP.Net 5 and C# 6

Two runtimes• .Net Core

• Sub-set of full framework• No Windows Forms, WPF, Silverlight• As I understand, no Web Forms (as no System.Web)• Also no System.Drawing

• Implemented as set of NuGet packages• Cross-platform and Nano server support

• .Net Full Framework• Not going away… so Windows hosting with full access

to .Net APIs remain

Page 7: ASP.Net 5 and C# 6

Open source• Large parts of the framework are fully open-

source

Page 8: ASP.Net 5 and C# 6

Working environment• Dynamic compilation

• Change C# code and refresh – no build needed• Can still publish to deploy pre-compiled code

• Embraced front-end community ecosystems• npm and bower• Gulp and grunt

Page 9: ASP.Net 5 and C# 6

Request pipeline• Lightweight web request handling

• Currently ASP.Net suffers in comparison to other frameworks due to the overhead in the pipeline of handling web requests

• Start with nothing and configure the middleware you need

• Middleware components can process the request with a response, or modify the request/response and pass it on

• Middleware replaces HttpModules

Page 10: ASP.Net 5 and C# 6

public void Configure(IApplicationBuilder app){ app.UseStaticFiles(); app.UseIdentity(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller}/{action}/{id?}", defaults: new { controller = "Home", action = "Index" }); });}

Page 11: ASP.Net 5 and C# 6

Solutions and projects• Global.json

Solution level configuration – project references (replaces .sln)

• Project.jsonProject level configuration – references, frameworks, dependencies (replaces .csproj and packages.config)

• WwwrootRoot of project != root of website, more secure, client side files live here

• Startup.csConfigures application start-up (replaces Global.asax)

Page 12: ASP.Net 5 and C# 6

Configuration• No more web.config, instead config.json

• Internal references can be set-up within the configuration

• XML or other sources can be used too• The methods used are configured in application

start-up (see later example)

Page 13: ASP.Net 5 and C# 6

{ "MyAppSetting": "MyAppSettingValue", "Data": { "DefaultConnection": { "ConnectionString": "Server=..." } }, "EntityFramework": { "ApplicationDbContext": { "ConnectionString": "Data:DefaultConnection:ConnectionString" } } }

Page 14: ASP.Net 5 and C# 6

public class HomeController : Controller{ private readonly IConfiguration _config; public HomeController(IConfiguration config) { _config = config; } public IActionResult Index() { var configSetting = _config.Get("MyAppSetting"); }}

Page 15: ASP.Net 5 and C# 6

Application start-up• The application is configured on start-up via the

three parts of Startup.cs• Constructor

• Wires up configuration• ConfigureServices() method

• Specify what services the application will use• Configure() method

• Sets up the required middleware and request pipeline

Page 16: ASP.Net 5 and C# 6

public Startup(IHostingEnvironment env){

Configuration = new Configuration().AddJsonFile("config.json").AddEnvironmentVariables();

}

public void ConfigureServices(IServiceCollection services){

services.AddEntityFramework(Configuration).AddSqlServer().AddDbContext<ApplicationDbContext>();

services.AddIdentity<ApplicationUser, IdentityRole>(Configuration).AddEntityFrameworkStores<ApplicationDbContext>();

services.AddMvc();

services.AddSingleton(_ => Configuration);}

Page 17: ASP.Net 5 and C# 6

public void Configure(IApplicationBuilder app){

// Add static files to the request pipeline.app.UseStaticFiles();

// Add cookie-based authentication to the request pipeline.app.UseIdentity();

// Add MVC and routing to the request pipeline.app.UseMvc(routes =>{routes.MapRoute(

name: "default",template: "{controller}/{action}/{id?}",defaults: new { controller = "Home", action = "Index" });

});

Page 18: ASP.Net 5 and C# 6

Dependency injection• Commonly used pattern – SOLID – usually

supported with a third party IoC container• ASP.Net 5 has it’s own simple one, suitable for

most requirements• Can even be injected into a view

Page 19: ASP.Net 5 and C# 6

public interface IService{

int GetResult();}

public class SimpleService : IService{

public int GetResult() { return 99; }}

public class HomeController : Controller{

private readonly IService _service; public ServiceController(IService service){

_service = service;} public int Get(){

return service.GetResult();}

}

public void ConfigureServices(IServiceCollection services){

services.AddSingleton<IService, SimpleService>(); // or AddScoped(), or AddTransient()}

Page 20: ASP.Net 5 and C# 6

public void ConfigureServices(IServiceCollection services){

services.AddSingleton<IService, SimpleService>();

// or AddScoped(), or AddTransient()}

Page 21: ASP.Net 5 and C# 6

ASP.Net MVC 6• MVC and Web API combined

• All controller action methods now return IActionResult – which might be a view for MVC or JSON for an API

• New features• View components• Tag helpers

Page 22: ASP.Net 5 and C# 6

ASP.Net MVC 6: View Components• View components replace @Html.Action()• They live outside of the controller but can still

access services via dependency injection• Wired up by convention

• Located via attribute and/or class name suffix• Base class not essential but provides access to

useful information and services

Page 23: ASP.Net 5 and C# 6

[ViewComponent(Name = "PromotedProducts")]public class PromotedProductsViewComponent : ViewComponent{

private readonly IProductService _productService;

public PromotedProductsViewComponent(IProductService productService){

_productService = productService;}

public async Task<IViewComponentResult> InvokeAsync(

int numberOfProducts){

var products = await _productService.GetPromotedProducts() .Take(numberOfProducts);

return View(products);}

}

<div>@await Component.InvokeAsync("PromotedProducts", 5)

</div>

Page 24: ASP.Net 5 and C# 6

ASP.Net MVC 6: Tag Helpers• Replacement/improvement on HTML helpers• Intermingling of front-end/back-end code

• More intuitive for FEDs to use – no more idiosyncratic anonymous typed HTML attributes

Page 25: ASP.Net 5 and C# 6

<form asp-controller="Products" asp-action="Create" method="post"><div>

<label asp-for="Name">Name:</label><input asp-for="Name" />

</div>

<input type="submit" value="Save" /></form>

...

<li><a asp-controller="Home" asp-action="Index“ class="home-link">Home</a></li>

<!– Instead of: --><li>@Html.ActionLink("Home", "Index", "Home", new { @class = "home-link")</li>

Page 26: ASP.Net 5 and C# 6

C# 6

Page 27: ASP.Net 5 and C# 6

C# 6• Available with VS.Net 2015 and the Roslyn

compiler• Brings a mix of nice little features

• Saves some typing• Avoid some bugs• General “syntactic sugar”

Page 28: ASP.Net 5 and C# 6

Null conditional (or “Elvis”) operator• Helps with handling NullReferenceExceptions• On encountering a null value, the whole

expression immediately returns null• ?. =

Page 29: ASP.Net 5 and C# 6

public static string Truncate(string value, int length){

var result = value;if (value != null){

result = value.Substring(0, Math.Min(value.Length, length));}

return result;}

public static string Truncate(string value, int length){

return value?.Substring(0, Math.Min(value.Length, length));}

public static int GetCustomerCount(IList<Customer> customers){

return customers?.Length ?? 0;}

Page 30: ASP.Net 5 and C# 6

Nameof expression• Used in situations where you want to return in

code the name of a variable• Without them, danger is that the variable name

change in a refactor is missed in the string• Handy in logging or exception guard clauses

Page 31: ASP.Net 5 and C# 6

public void DoSomething(string data){

if (data == null){

throw new ArgumentNullException("data");}

}

public void DoSomething(string data){

if (data == null){

throw new ArgumentNullException(nameof(data));}

}

Page 32: ASP.Net 5 and C# 6

String interpolation• A nicer, easier to write and follow syntax for

string formatting• Formatting variables are placed in-line within the

string• Existing string.Format() syntax can be fiddly to

line up arguments and lead to tricky bugs

Page 33: ASP.Net 5 and C# 6

var s = string.Format("{0} is {1} year{2} old", p.Name, p.Age, p.Age == 1 ? "" : "s");

...

var s = $"{p.Name} is {p.Age} year{(p.Age == 1 ? "" : "s")} old";

Page 34: ASP.Net 5 and C# 6

Expression bodied methods• More succinct format for one-liner methods• Need to consider code readability and consistency

when adopting use

Page 35: ASP.Net 5 and C# 6

public static int Add(int arg1, int arg2){

return arg1 + arg2;}

public static int Add(int arg1, int arg2) => arg1 + arg2;

Page 36: ASP.Net 5 and C# 6

Auto-property initialisers• Allows setting a default value for an instance of a

class, without writing this code in the constructor• Useful for collection initialisers – ensuring you

return empty collections instead of nulls• Used in conjunctions with primary constructors

where variables provided for auto-initialisation

Page 37: ASP.Net 5 and C# 6

public class Customer {

public Customer() {

FirstName = "Fred";LastName = "Bloggs";

}

public string FirstName { get; set; }

public string LastName { get; set; }}

public class Customer {

public string FirstName { get; set; } = "Fred";

public string LastName { get; set; } = "Bloggs"; }

public IList<Customer> Customers { get; set; } = new List<Customer>();

Page 38: ASP.Net 5 and C# 6

public class Customer {

public Customer(string firstName, string lastName) {}

public string FirstName { get; set; } = firstName;

public string LastName { get; set; } = lastName; }

Page 39: ASP.Net 5 and C# 6

Out parameter declaration in method call• Allows an out variable to be declared as it is

used.• Small improvement to save a bit of typing – less

code, less bugs!

Page 40: ASP.Net 5 and C# 6

public bool IsOver18 (string age){ int ageAsNumber; if (int.TryParse(value, out ageAsNumber)) {

return ageAsNumber > 18; }

return false;}

...

public bool IsOver18 (string age){ return int.TryParse(value, out int ageAsNumber) && ageAsNumber > 18;}

Page 41: ASP.Net 5 and C# 6

Using a static class• Allows a static class to be referenced as a using• Another simple one that removes a bit of clutter• Question here though whether this really

improves readability, so likely one to use with care

Page 42: ASP.Net 5 and C# 6

using System;

public class Program{

public static void Main(string[] args){

Console.WriteLine("A");Console.WriteLine("B");

}}

using System;using System.Console;

public class Program{

public static void Main(string[] args){

WriteLine("A");WriteLine("B");

}}

Page 43: ASP.Net 5 and C# 6

Exception handling enhancements• Try/catch blocks have always allowed for

targeting particular exceptions• With C# 6 you can apply further filters• Asynchronous code is also now usable in catch

blocks

Page 44: ASP.Net 5 and C# 6

try{

// ...}catch (Exception exception) if (expression){

// ...}

try{

// ...}catch (Exception exception){

await WriteErrorToLog(exception);}

Page 45: ASP.Net 5 and C# 6

In closing…• ASP.Net 5 is coming… time to get up to speed,

even if not going to be using it directly for a while• C# 6 is available now with VS.Net 2015

Page 46: ASP.Net 5 and C# 6

Provided as Creative Commons 3.0 Share Alike:

http://creativecommons.org/licenses/by-nc-sa/3.0/