$30 off During Our Annual Pro Sale. View Details »

Moderne APIs mit ASP.NET Core MVC und SignalR – End-to-End

Moderne APIs mit ASP.NET Core MVC und SignalR – End-to-End

Moderne APIs bieten neben der gängigen HTTPS-Interaktion auch die Möglichkeit zur Echtzeitkommunikation auf Basis von WebSockets. Mit Hilfe von Microsofts Open-Source-Plattform ASP.NET Core MVC und SignalR lassen sich im Handumdrehen Web-APIs und Push-Services entwickeln. Doch damit nicht genug: Weitere Themen wie Security, Rate-Limiting, eine sinnvolle Dokumentation und ein vernünftiges zentralisiertes Logging sind mit von der Partie. Und jeder dieser einzelnen Bereiche bietet uns eine neue Herausforderung. Sebastian Gingter und Manuel Rauber zeigen Ihnen in diesem Workshop, wie man mit .NET Core moderne APIs auf und für verschiedene Plattformen entwickeln kann. Zusätzlich wird durch den Einsatz von Entity Framework Core die Anbindung an verschiedene Datenbanken ermöglicht. Durch den Einsatz weiterer Open-Source-Bibliotheken fürs Logging oder zur automatischen Generierung einer Swagger/OpenAPI-Dokumentation ergänzen wir die API um weitere Funktionalitäten. Eine Client-Anwendung, das Deployment auf unterschiedliche Plattformen und das Deployment in die Cloud runden den Workshop ab – vollständig End-to-End eben!

GitHub: https://github.com/thinktecture/api-ms-summit-spring-2018-services-dotnetcore

Manuel Rauber

June 13, 2018
Tweet

More Decks by Manuel Rauber

Other Decks in Programming

Transcript

  1. Moderne APIs – End-to-End
    Mit ASP.NET Core Web APIs & SignalR
    Sebastian Gingter Manuel Rauber
    @PhoenixHawk @ManuelRauber
    Consultant Consultant

    View Slide

  2. Speakers
    [email protected]
    @manuelrauber
    https://manuel-rauber.com
    Microsoft MVP
    [email protected]
    @PhoenixHawk
    https://gingter.org/

    View Slide

  3. Time Doing
    09:00 – 10:30 Part I
    10:30 – 11:00 ☕
    11:00 – 12:30 Part II
    12:30 – 13:30 " # $ %
    13:30 – 15:00 Part III
    15:00 – 15:30 ☕ & &
    15:30 – 17:00 Part IV
    17:00 – open end ''''
    Timetable

    View Slide

  4. • Lightweight service-based architecture
    • Functional services with dedicated interfaces
    • Use other services, like database or file system
    • (JSON-based) HTTPS Web APIs
    • Application push services via WebSocket
    • SignalR
    • Socket.io
    Target Architecture
    HTTP HTTPS WebSocket
    Service A Service B Service C
    Web APIs
    (ASP.NET, Node.js, …)
    HTML5-Application
    (Single-Page Application)
    Web Cordova Electron

    View Slide

  5. • Functional services with dedicated interfaces
    • Strict REST services do not model real world
    • Better: Design interfaces according to use case
    • Single Web API can use multiple backend services
    • (JSON-based) HTTPS Web APIs
    • Embraces usage of common denominator
    • Content Negotation
    • HTTP Status Codes
    • Resources are mapped to URLs
    • Lightweight & scalable
    Target Architecture
    HTTP HTTPS WebSocket
    Service A Service B Service C
    Web APIs
    (ASP.NET, Node.js, …)
    AuthN & AuthZ
    Client

    View Slide

  6. The new cool kid in town
    .NET Standard

    View Slide

  7. Application Models & Libraries
    .NET today
    https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/

    View Slide

  8. Challenges
    • Mastering different kind of base class libraries
    • Hard to reuse skills
    • Common denominator needed for code reusage
    • Hard to reuse code
    • Fiddling with a lot of interfaces
    • ”Having fun with retargeting PCLs” J
    • Implementation needed on each platform
    .NET today

    View Slide

  9. Common denominator – Flashback 2014
    .NET today
    Platform Code
    Interfaces
    All others:
    Shared code with
    platform switches

    View Slide

  10. One library to rule them all
    .NET tomorrow
    https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/

    View Slide

  11. Benefits
    • One base library to learn, not one per .NET platform
    • Easy code reuse due to a bigger API surface area
    • .NET standard can be updated without having all platforms to be updated
    • Faster and independent update cycles
    .NET tomorrow

    View Slide

  12. What exactly is it?
    • .NET Standard is an open source specification: https://github.com/dotnet/standard
    • Represents a common set of API to be implemented by all .NET platforms
    • .NET Standard will replace PCLs
    .NET Standard
    “.NET Standard solves the code sharing problem for .NET developers across all
    platforms by bringing all the APIs that you expect and love across the
    environments that you need: desktop applications, mobile apps & games, and
    cloud services.”
    - Immo Landwerth
    https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/

    View Slide

  13. 2.0
    Differences to PCLs
    Portable Class Libraries .NET Standard
    .NET Standard
    Profile A
    Profile B Profile C
    Intersection Profile: Possible Platform targets


    1.1
    1.0
    Higher versions are backwards
    compatible to lower versions.

    View Slide

  14. Versioning
    • Additive: Higher versions incorporate all APIs from previous versions.
    • There are no breaking changes between versions
    • Immutable: After shipping, the version is frozen
    .NET Standard

    View Slide

  15. Versioning
    .NET Standard
    https://github.com/dotnet/standard/blob/master/docs/versions.md

    View Slide

  16. Versioning
    • Higher version
    • more capabilities
    • more APIs
    • higher code reuse
    • less platform support
    • Lower version
    • less capabilities
    • less APIs
    • (maybe) lower code reuse
    • better platform support
    .NET Standard

    View Slide

  17. Targeting
    • Represented by NuGet package NetStandard.Library containing assembly netstandard.dll
    • in fact: everything’s a NuGet package within the new .NET Standard world
    • Build Time
    • .NET Standard bridges references to existing .NET Framework and PCL assemblies via
    type forwarding
    • Run Time
    • Each platform provides an implementation for netstandard.dll that type forwards to its
    own implementation
    .NET Standard 2.0

    View Slide

  18. Targeting
    .NET Standard 2.0
    https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/

    View Slide

  19. Targeting @ Build Time
    .NET Standard 2.0
    Your .NET
    Standard-based
    Class Library
    .NET Framework
    or PCL
    netstandard.dll
    mscorlib.dll
    netstandard!Object
    mscorlib!Object
    Different Type
    Identities
    Type Forwarding
    https://www.slideshare.net/terrajobst/net-standard-under-the-hood

    View Slide

  20. Targeting @ Build Time
    .NET Standard 2.0
    Your .NET
    Standard-based
    Class Library
    .NET Framework
    or PCL
    netstandard.dll
    mscorlib.dll
    Type Forwarding
    mscorlib.dll
    mscorlib.dll
    Framework
    Assemblies
    https://www.slideshare.net/terrajobst/net-standard-under-the-hood

    View Slide

  21. Targeting @ Run Time
    .NET Standard 2.0
    Your .NET
    Application
    Framework
    Assemblies
    Your .NET
    Standard-based
    Class Library
    netstandard.dll
    Type Forwarding
    https://www.slideshare.net/terrajobst/net-standard-under-the-hood

    View Slide

  22. Platform-specific APIs
    • .NET Standard (mostly) contains APIs that run everywhere
    • A small subset will throw PlatformNotSupportedException
    • e.g. Registry, Reflection Emit, Windows Identity
    .NET Standard

    View Slide

  23. Platform-specific APIs
    • Conditional compilation
    • VS 2017 provides information about type availability
    • IDE Tool
    • Roslyn Analyzer to find problematic APIs
    • https://github.com/terrajobst/platform-compat
    .NET Standard
    #if NETSTANDARD1_3 || NETSTANDARD1_4
    var code = TypeCode.Boolean;
    #endif

    View Slide

  24. Summary
    • Simple, yet powerful idea for creating cross-platform-targeting .NET libraries and applications
    • Good and growing API support
    • No breaking changes between versions
    • Using platform code could shrink targeting platforms
    • Targeting platform specific APIs could result in an error or conditional compilation
    .NET Standard

    View Slide

  25. Security Token Service
    Identity Server
    Database Todo-
    API
    Push-
    API
    Realtime-Data
    Users
    Web-Server
    SPA (static files)
    Demo Architecture

    View Slide

  26. Security Token Service
    Identity Server
    Database Todo-
    API
    Push-
    API
    Realtime-Data
    Users
    Web-Server
    SPA (static files)
    Demo Architecture

    View Slide

  27. Demo Client Application

    View Slide

  28. From specification to implementation
    .NET Core

    View Slide

  29. Overview
    • .NET Core is an open source implementation of the .NET Standard specification:
    • https://github.com/dotnet/core
    • Runs on Linux, macOS and Windows
    • CLI tools available
    • Supports C# and F#
    • Compatible to .NET Framework, Xamarin and Mono (due to .NET Standard)
    • Fully supported by Microsoft (LTS support three years after GA)
    .NET Core

    View Slide

  30. Deployment
    • Offers flexible deployment possibilities
    • included within the app (self-contained deployments)
    • multiple versions can be installed side-by-side (framework-dependent deployments)
    • can be installed per user or machine-wide
    • Cloud-ready
    .NET Core

    View Slide

  31. Application Models
    • Shipped with .NET Core
    • Console Applications
    • Built on top of .NET Core
    • ASP.NET Core
    .NET Core

    View Slide

  32. IDEs
    .NET Core
    VS 2017
    VS Code JetBrains Rider
    VS for Mac

    View Slide

  33. Use case depending alternatives
    • Node.js
    • JavaScript, TypeScript, CoffeeScript, …
    • Restify, Express, Koa.js
    • TypeORM, SequelizeJS, ORM
    • Node Package Manager, YARN
    • Java
    • Jersey, RESTful WebServices
    • Hibernate, ORM
    • Maven, Package Management
    • Ruby, Python, …
    .NET Core

    View Slide

  34. Summary
    • .NET Core is an implementation of .NET Standard
    • Runs cross-platform on Linux, macOS and Windows
    • Can be installed side-by-side
    • Cloud-ready
    .NET Core

    View Slide

  35. Cross-Platform Web Application & Web APIs
    ASP.NET Core

    View Slide

  36. Overview
    • Unifies MVC and Web APIs
    • Built-in dependency injection
    • Cloud-ready configuration system
    • HTTP Request Pipeline
    • Hostable in IIS or as Self Host
    • Everything’s a NuGet Package
    • Leads to having a lot packages installed (“Hello node_modules J”)
    • Built on .NET Core
    • Open Source, https://github.com/aspnet/Home
    • “Can I port my application to .NET Core?”
    • https://icanhasdot.net/
    ASP.NET Core

    View Slide

  37. Compared to ASP.NET
    ASP.NET Core
    • Runs on Linux, macOS, Windows
    • C#, F#
    • MVC & Web API, Razor Pages
    • SignalR is in development
    • New platform, new toolings
    • Multiple versions per machine
    • MSDN: “Ultra Performance”
    ASP.NET
    • Runs on Windows
    • C#, F#, VB.NET
    • MVC, Web API, WebForms, WebPages,
    SignalR
    • Mature platform
    • One version per machine
    • MSDN: “High Performance”
    ASP.NET Core

    View Slide

  38. Hosting
    • Kestrel: ASP.NET Core’s Web Server
    • IISIntegration to host in IIS
    • Mandatory for App Services
    • Specifies a class used
    for Startup configuration
    ASP.NET Core
    public class Program
    {
    public static void Main(string[] args)
    {
    var host = new WebHostBuilder()
    .UseKestrel()
    .UseContentRoot(Directory.GetCurrentDirectory())
    .UseIISIntegration()
    .UseStartup()
    .Build();
    host.Run();
    }
    }

    View Slide

  39. Startup
    • ConfigureServices: Used for configuring the built-in dependency injection
    • Configure: Used for configuring the HTTP pipeline via IApplicationBuilder
    ASP.NET Core
    public class Startup
    {
    public void ConfigureServices(IServiceCollection services) { }
    public void Configure(IApplicationBuilder app,
    IHostingEnvironment env, ILoggerFactory loggerFactory) { }
    }

    View Slide

  40. Dependency Injection
    • Built-in dependency injection
    • Constructor injection should be preferred over direct DI container access
    • Overriding the container is possible, e.g. to use AutoFac instead
    • Throws an error when a dependency could not be resolved (e.g. wrong container configuration)
    ASP.NET Core

    View Slide

  41. Dependency Injection
    • Supports three lifetimes
    • Transient: Creates an instance each it is requested
    • Scoped: Creates an instance once per request
    • Singleton: Creates an instance once per application
    ASP.NET Core
    public void ConfigureServices(IServiceCollection services)
    {
    services.AddTransient();
    services.AddScoped();
    services.AddSingleton();
    }

    View Slide

  42. Pipeline
    • Customizable HTTP pipeline
    • Every request will run through
    • Order in code defines the order of the pipeline
    • Nesting of pipelines is possible
    • IApplicationBuilder is used to define the pipeline
    ASP.NET Core
    https://docs.microsoft.com/en-us/aspnet/core/fundamentals/middleware
    public void Configure(IApplicationBuilder app)
    {
    app.UseExceptionHandler("/Home/Error");
    app.UseStaticFiles();
    app.UseMvcWithDefaultRoute();
    }
    Middleware 1
    // Server logic
    next()
    // more logic
    Middleware 2
    // Server logic
    next()
    // more logic
    Middleware 3
    // Server logic
    // more logic
    Request
    Response
    Client
    Logging Authentication …

    View Slide

  43. Multiple Environments
    • Support multiple environments like Development, Staging or Production out-of-box
    • Can be set via environment variable ASPNETCORE_ENVIRONMENT
    • Convention based application startup
    • Startup, StartupDevelopment, Startup{Environment}
    • Careful, using webhostBuilder.UseStartup() overrides this behavior
    • Configure, ConfigureDevelopment, Configure{Environment}
    • ConfigureServices, ConfigureDevelopmentServices, Configure{Environment}Services
    ASP.NET Core

    View Slide

  44. Multiple Environments
    IHostingEnvironment for checking environment at runtime
    ASP.NET Core
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    if (env.IsDevelopment() || env.IsProduction() || env.IsStaging() || env.IsEnvironment(”MyEnv"))
    { }
    }

    View Slide

  45. Configuration System
    • ConfigurationBuilder is used to define configuration sources
    • Order is used for configuration overriding, later defined sources override previous defined
    • Optional sources and sources depending on the environment are possible
    ASP.NET Core
    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();
    }

    View Slide

  46. Authentication
    • Middleware within the pipeline
    • “Plug & Play” solutions for authentication
    • ASP.NET Identity
    • IdentityServer 4, open source project
    • Different authentication schemes
    • Cookies
    • Bearer
    • Basic
    • External providers
    • Custom
    ASP.NET Core

    View Slide

  47. Controllers
    • Two base classes for controllers
    • ControllerBase: Preferred for Web APIs, offers everything except Views
    • Controller: Preferred for MVC, inherits from ControllerBase and adds View capabilities
    • Offer various methods for returning a result
    • Ok() / NotFound() / StatusCodeResult()
    • FileResult() / FileContentResult() / FileStreamResult()
    • Offers access to authenticated user via User property
    • Can be asynchronous using async/await pattern
    • If enabled, automatic Content Negotiation
    ASP.NET Core

    View Slide

  48. Routing
    • Routing: Mapping URLs to actions (methods within a controller)
    • Routing via definition in pipeline
    • Routing via attributes
    • Routing via custom routing handler
    • Support for all important HTTP verbs like GET, POST, PUT, DELETE
    ASP.NET Core
    public void Configure(IApplicationBuilder app) =>
    app.UseMvc(routes => routes.MapRoute("api", "{controller}/{action}"));
    [Route("customers")]
    public class CustomerApiController : ControllerBase
    {
    [HttpGet("{id:int}")]
    public IActionResult Get(int id) { }
    }

    View Slide

  49. Error Handling
    • Provides a developer exception page with detailed information about errors
    • Supports error page per status code or custom error pages
    • Supports custom error filter per action, controller or globally
    ASP.NET Core
    public void Configure(IApplicationBuilder app)
    {
    // Use in development only
    app.UseDeveloperExceptionPage();
    // Simple status code error pages
    app.UseStatusCodePages();
    // Custom error handler
    app.UseExceptionHandler("/error");
    }

    View Slide

  50. Swagger Help Pages
    • NuGet: Swashbuckle.AspNetCore
    • Swagger: Generates a swagger.json containing all information about your Web APIs
    • Swagger UI: Provides a basic UI to view the swagger.json
    ASP.NET Core
    public void ConfigureServices(IServiceCollection services)
    {
    services.AddSwaggerGen(options =>
    {
    options.SwaggerDoc("v1", new Info() { Title = "Awesome Customer API", Version = "1.0" });
    });
    }
    public void Configure(IApplicationBuilder app)
    {
    app.UseSwagger();
    app.UseSwaggerUI(options => { options.SwaggerEndpoint("v1/swagger.json", "API v1"); });
    }

    View Slide

  51. Swagger Help Pages
    ASP.NET Core

    View Slide

  52. • Built-in logging
    • Third party logging solutions (e.g. Serilog, Nlog) can be easily integrated without changing the
    logging API
    Logging
    public class SampleController : ControllerBase {
    private readonly ILogger _logger;
    public SampleController(ILogger logger)
    {
    _logger = logger;
    }
    [HttpGet]
    public IActionResult Get(int listId, string listName)
    {
    _logger?.LogDebug($"{nameof(SendListCreated)}: {{ListId}}, {{ListName}}", listId, listName);
    // Useful code
    }
    }

    View Slide

  53. • https://github.com/stefanprodan/AspNetCoreRateLimit
    • Public APIs
    • DDoS protection
    • Pay per request APIs
    • Rates for “expensive” resources
    • Rates per timeframe: Hour, Minute, Second
    • How?
    • IP-based
    • Account-based
    Rate Limiting
    public void ConfigureServices(IServiceCollection services)
    {
    services
    .Configure(Configuration.GetSection("IpRateLimiting"))
    .Configure(Configuration.GetSection("IpRateLimitPolicies"))
    .AddSingleton()
    .AddSingleton();
    }
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    app.UseIpRateLimiting();
    }

    View Slide

  54. • Tell client that the data did not change
    • HTTP Status Code 304
    • Two standardized options
    • Last Modified Header: Did data change since …?
    • Etag-Header: Checksum of data
    • e.g.: https://github.com/KevinDockx/HttpCacheHeaders
    Reduce traffic
    Initial request
    GET /item/1
    OK 200
    Etag: 123123123123
    Following request
    GET /item/1
    If-None-Match: 123123123123
    304 Not Modified

    View Slide

  55. • Supported by all modern browsers
    • Supported by most servers
    • Reduces traffic by up to 70 %
    • But
    • more computation on server and client
    • is not always smaller
    • https://docs.microsoft.com/en-us/aspnet/core/performance/response-compression
    GZIP
    public void ConfigureServices(IServiceCollection services)
    {
    services.AddResponseCompression();
    }
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    app.UseResponseCompression();
    }

    View Slide

  56. • Via URL (api.com/v1/item/1)
    • Via Accept-Header
    • Via Custom-Header
    • https://github.com/Microsoft/aspnet-api-versioning
    Versioning
    public class Startup
    {
    public void ConfigureServices(IServiceCollection services)
    {
    services.AddMvc();
    services.AddApiVersioning();
    }
    }
    [ApiVersion("1.0")]
    [Route("[controller]")]
    public class PeopleController : Controller
    {
    [HttpGet]
    public IActionRoute Get() => Ok(new[] { new Person() });
    }

    View Slide

  57. • Hypermedia as the engine of application state
    • Navigate from anywhere to everywhere
    • Usage of API without prior knowledge
    HATEOAS

    View Slide

  58. • Example: POST
    • Example: Pagination
    HATEOAS
    POST /items
    201 Created
    Location: https://api.io/item/3
    GET /items?page=1&size=10
    200 OK
    Link:
    ; rel=“next”,
    ; rel=“last”

    View Slide

  59. • Bi-directional real time communication server <-> client
    • Integrates into the whole ASP.NET Core universe (Routing, Dependency Injection)
    • No jQuery dependency on client-side anymore!!!!111
    • Usable not only on client-side JavaScript, but in Node.js or Web Workers
    • Browser support: IE 11, all evergreens
    SignalR

    View Slide

  60. Integrate into ASP.NET Core pipeline
    Add NuGet “Microsoft.AspNetCore.SignalR” (included by default)
    SignalR
    public void ConfigureServices(IServiceCollection services)
    {
    services.AddSignalR();
    }
    public void Configure(IApplicationBuilder app, IHostingEnvironment env)
    {
    app.UseSignalR(routes =>
    {
    routes.MapHub("/chathub");
    });
    }

    View Slide

  61. Hub
    • Represents a high-level pipeline allowing clients and
    servers to call methods on each other.
    • Bridges dispatching messages between client and
    server to easily call methods.
    • Strongly-typed parameters, model binding
    • Text protocol on JSON, binary protocol on MessagePack
    SignalR
    Hubs
    Endpoints
    Clients
    Transport
    WebSocket
    Server-Sent Events
    Long Polling
    Built on top of
    Text/Binary protocol
    via
    JSON/MessagePack
    public class ChatHub : Hub
    {
    public async Task SendMessage(string user, string message)
    {
    await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
    }

    View Slide

  62. JavaScript Client
    • Install via NPM: @aspnet/signalr
    • Don’t forget CORS!
    • Possibility to receive and invoke methods
    • Third party modules for RxJS integration
    SignalR
    const connection = new signalR.HubConnection(
    "/chathub", { logger: signalR.LogLevel.Information });
    connection.on("ReceiveMessage", (user, message) => {
    // Do something with the payload
    });
    // Send something (e.g. via button)
    connection.invoke("SendMessage", user, message).catch(err => console.error);
    // Start the connection
    connection.start().catch(err => console.error);

    View Slide

  63. Summary
    • Unifies MVC and Web APIs
    • Built-in dependency injection
    • Cloud-ready
    • HTTP Pipeline & Configuration System
    • Several hosting options
    • Help Pages via Swagger
    • Don’t forget gzip, versioning, rate limiting, …
    • SignalR enables real time connections for server -> client communication scenarios
    ASP.NET Core

    View Slide

  64. Lightweight & cross-platform data access
    EntityFramework Core

    View Slide

  65. Overview
    • Open source implementation: https://github.com/aspnet/EntityFramework
    • Lightweight & cross-platform version of .NET’s full-fledged EntityFramework
    • Support different database providers
    • MS SQL
    • SQLite
    • Postgres
    • InMemory
    • Offers Commandline Tools
    • Code First, Database First
    • Migrations
    EntityFramework Core

    View Slide

  66. Compared to EntityFramework 6
    • EntityFramework Core does offer the following features, but some of them are still in
    development
    • Complex value types (without an ID)
    • Spatial data (geography, geometry) (in development)
    • Graphical visualization of the model (Model First) (in development)
    • Complex LINQ-Queries
    • Many-to-Many without a joining entity (in development)
    • Lazy Loading
    • Stored Procedures
    • Data Seeding (via model definition)
    • Full list available at https://docs.microsoft.com/en-us/ef/efcore-and-ef6/features
    EntityFramework Core

    View Slide

  67. NuGet Package & CLI
    • Core Package: Microsoft.EntityFrameworkCore
    • Database Provider Packages
    • MS SQL: Microsoft.EntityFrameworkCore.SqlServer
    • Postgres: Npgsql.EntityFrameworkCore.PostgreSQL
    • SQLite: Microsoft.EntityFrameworkCore.SQLite
    • CLI Tools
    • Powershell: Microsoft.EntityFrameworkCore.Tools
    • cmd/bash: Microsoft.EntityFrameworkCore.Tools.DotNet
    • Careful: cmd/bash is not installable via NuGet, only by editing .csproj directly
    EntityFramework Core

    View Slide

  68. Model
    • Working with EntityFramework Core is based on a model
    • A model is a simple class with specific attributes
    EntityFramework Core
    public class CustomerEntity
    {
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id { get; set; }
    [Required]
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public int Age { get; set; }
    }

    View Slide

  69. Database Context
    • A database context (DbContext) represents a session to the database
    • Has one or multiple DbSet to query the database
    • Allows executing raw SQL queries
    EntityFramework Core
    public class SampleApplicationDbContext : DbContext
    {
    public SampleApplicationDbContext(DbContextOptions options)
    : base(options)
    {
    // Overriding constructor is necessary to make use of DbContextOptions
    }
    public DbSet Customers { get; set; }
    }

    View Slide

  70. Database Context
    • DbContext can be added to the dependency injection
    • Services can request a DbContext via constructor injection
    EntityFramework Core
    public void ConfigureServices(IServiceCollection services)
    {
    services.AddDbContext(options =>
    {
    options.UseSqlServer(Configuration.GetConnectionString("SampleApplication"));
    }
    );
    }
    public class CustomerService
    {
    public CustomerService(SampleApplicationDbContext dbContext)
    { }
    }

    View Slide

  71. Fluent API
    • Instead of using attributes to define a model, the Fluent API can be used
    • Fluent API has a richer API than the attributes for more complex scenarios
    EntityFramework Core
    public class SampleApplicationDbContext : DbContext
    {
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
    modelBuilder.Entity()
    .HasKey(e => e.Id);
    modelBuilder.Entity()
    .Property(e => e.FirstName)
    .IsRequired();
    }
    }

    View Slide

  72. Querying
    • LINQ for database querying
    • Simple selects
    • Ordering
    • Grouping
    • Limiting
    • Can load related data
    • Eager Loading
    • Explicitly
    • Lazy Loading (soon)
    EntityFramework Core
    public class CustomerService
    {
    private readonly SampleApplicationDbContext _dbContext;
    public CustomerService(SampleApplicationDbContext dbContext)
    {
    _dbContext = dbContext;
    }
    public ICollection List()
    {
    return _dbContext.Customers
    .OrderBy(c => c.Id)
    .ToList();
    }
    }

    View Slide

  73. Saving
    • Tracks changes on entities per default
    • Writes back changes to the database when the DbContext is saved
    EntityFramework Core
    public void Update()
    {
    var entity = _dbContext.Customers.First();
    entity.FirstName = "Max";
    _dbContext.SaveChanges();
    }

    View Slide

  74. Saving
    • Related data is also saved on change tracked entities
    • Use AsNoTracking() when querying to not track changes, e.g. for read-only scenarios
    EntityFramework Core
    public ICollection List()
    {
    return _dbContext.Customers
    .AsNoTracking() .ToList();
    }

    View Slide

  75. Transactions
    • SaveChanges() calls done as a transaction by default
    • Custom transaction can be create by using DbContext.Database.BeginTransaction()
    EntityFramework Core
    using (var transaction = _dbContext.Database.BeginTransaction())
    {
    try
    {
    _dbContext.Customers.Add(new CustomerEntity { FirstName = "Max" });
    _dbContext.SaveChanges();
    _dbContext.Customers.Add(new CustomerEntity { FirstName = "Erika" });
    _dbContext.SaveChanges();
    transaction.Commit();
    }
    catch (Exception e)
    {
    // TODO: Handle exception
    }
    }

    View Slide

  76. Migrations
    • Needs the PowerShell or cmd/bash tools installed
    • Add Migrations via
    • PowerShell: Add-Migration MigrationName
    • cmd/bash: dotnet ef migrations add MigrationName
    • Custom database initializer is needed to actually apply the migrations on startup
    EntityFramework Core
    public class DatabaseInitializer
    {
    public void Migrate()
    {
    _dbContext.Database.Migrate();
    }
    }

    View Slide

  77. Summary
    • Cross-platform version of .NET’s EntityFramework
    • Not all features are supported yet
    • Offers PowerShell and cmd/bash toolings
    • Supports transactions & migrations
    • Support multiple database providers and an InMemory database for testing
    EntityFramework Core

    View Slide

  78. Summary
    • .NET Standard makes it easier to create multi-targeting code (replacing PCLs)
    • .NET Standard 2.0 can target existing .NET code to reuse your existing business logic
    • ASP.NET Core provides a cross-platform possibility for MVC & Web APIs
    • ASP.NET Core is cloud-ready and offers a customizable HTTP pipeline
    • EntityFramework Core provides cross-platform and cross-database capabilities
    .NET Core & ASP.NET Core & EntityFramework Core

    View Slide

  79. .NET Standard MSDN
    https://docs.microsoft.com/en-us/dotnet/articles/standard/library
    Introducing .NET Standard
    https://blogs.msdn.microsoft.com/dotnet/2016/09/26/introducing-net-standard/
    .NET Core MSDN
    https://docs.microsoft.com/en-us/dotnet/articles/core/
    ASP.NET Core MVC MSDN
    https://docs.microsoft.com/en-us/aspnet/core/mvc/overview
    ASP.NET Core Web API MSDN
    https://docs.microsoft.com/en-us/aspnet/core/mvc/web-api/
    EntityFramework Core MSDN
    https://docs.microsoft.com/en-us/ef/
    Resources

    View Slide

  80. Thank you! Questions?
    Repository
    Sebastian Gingter Manuel Rauber
    @PhoenixHawk @manuelrauber
    Consultant Consultant
    https://github.com/thinktecture/api-ms-summit-spring-2018-services-dotnetcore

    View Slide