Rainer Stropek | time cockpit
rainer@timecockpit.com | Blog | GitHub
Samples see GitHubAls .NET-Entwickler fragt man sich momentan oft, warum Microsoft so grundlegende Änderungen an .NET vornimmt. In ASP.NET 5 entdeckt man so viele neue Tools, Libraries und Konzepte, dass man leicht den Überblick verlieren kann. In dieser Session erklärt Rainer Stropek, was hinter den Umbaumaßnahmen von Microsoft an .NET steckt.
New to .NET? Need to introduce someone to .NET?
Quick overview
Different implementations
.NET Core
New, redesigned, cross-platform, open-source, ...
.NET Native
.NET adhead-of-time compiled
.NET Framework
Server, client, just Windows; huge .NET Framework Class Library incl. WCF, WPF, etc.
Mono
Community-driven, cross-platform, open-source; follows .NET Framework, not .NET Core
Contender: Node.js
.NET Runtime and framework
ECMA 335 implementation
Cross-platform
Windows, Linux and MacOS
Open-source
Delivered by package manager (NuGet, APT, etc.) or Docker
"A-la-carte" framework (take just what you need)
Manage packages for your application
Detailed reference (note --help
option)
.NET Execution Environment
dnx-watch
is useful during developmentproject.json
dnx run
fails
namespace myApp
{
public class Program
{
public static void Main(string[] args)
{
}
}
}
{
"frameworks": {
"dnx451": {},
"dnxcore50": {}
},
"commands": {
"run": "myApp"
}
}
Add dependency to System.Console
Use VS (IntelliSense) or run dnu install System.Console
Global or framework-specific dependencies
{
"dependencies": {
"System.Console": "4.0.0-beta-23516"
},
...
}
{
"dependencies": { },
"frameworks": {
"dnx451": {},
"dnxcore50": {
"dependencies": {
"System.Console": "4.0.0-beta-23516"
}
}
}, ...
}
Cache for package dependencies
Better performance because of significantly less disk IO
Generated when running dnu restore
Prerequisite for running dnx
locked
field used to suppress dependency graph walking
dnu [ --lock | --unlock ]
Entry points with arguments (used e.g. by EF 7 and Kestrel)
{
"dependencies": { },
"frameworks": { ... },
"commands": {
"run": "myApp --target world"
}
}
public static void Main(string[] args)
{
if (args.Length != 2 || args[0] != "--target") {
System.Console.WriteLine("Missing parameter --target");
}
else {
System.Console.WriteLine($"Hello {args[1]}");
}
}
Details about global commands
{
"compilationOptions": {
"define": ["SOMETHING"],
"allowUnsafe": true,
"warningsAsErrors" : true,
"languageVersion": "experimental"
}
}
Use configurations
to create named groups of settings
dnu build --configuration Debug
{
"configurations": {
"Debug": { "compilationOptions": { ... } },
"Release": { "compilationOptions": { ... } }
}
}
compile
: What should be compiled?
exclude
: What should be totally ignored?
publishExclude
: What should be ignored for publishing?
{
"compile": "*.cs",
"exclude": [
"node_modules",
"bower_components"
],
"publishExclude": [
"**.xproj",
"**.user",
"**.vspscc"
]
}
Use glob patterns
More details about include/exclude settings
Compile code in shared directory as if it was part of the project
Note: Use internal
types only
{
"dependencies": {
"System.Console": "4.0.0-beta-23516"
},
"frameworks": {
"dnxcore50": {}
},
"shared": "*.cs"
}
Projects are just folders with files in them
global.json
at the top level needs the names of each project (folder name)
{
"projects":[
"consumer",
"lib"
]
}
project.json
includes a reference
{
"dependencies": {
"lib": "",
...
},
...
}
Create NuGet package with DNU
dnu pack [ --configuration ... ]
{
"title": ".NET Core Demo",
"authors": [ "Rainer Stropek" ],
"version": "1.0.0",
"copyright": "MIT License",
"description": "This is small sample for .NET Core",
...
}
More details about package metadata
Add scripts to project.json
Used for e.g. npm
, gulp
, etc.
{
"scripts": {
"prebuild": "executed before building",
"postbuild": "executed after building",
"prepack": "executed before packing",
"postpack": "executed after packing",
"prepublish": "executed before publish",
"postpublish": "executed after publish",
"prerestore": "executed before restoring packages",
"postrestore": "executed after restoring packages",
"prepare": "After postrestore but before prepublish"
}
}
More details about scripts
Main
in our code or in referenced assemblies
See e.g. Kestrel's Main
method
public class Program
{
public void Main(string[] args) => WebApplication.Run<Startup>(args);
}
Startup
class is detected based on conventions
Supports multiple environments
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{ ... }
public void Configure(IApplicationBuilder app)
{ ... }
}
During startup, application services are available
List of services
public class Startup
{
// Note constructor injection here
public Startup(IApplicationEnvironment appEnv, IHostingEnvironment env)
{
Console.WriteLine($"App name: {appEnv.ApplicationName}");
Console.WriteLine($"Root path: {env.WebRootPath}");
}
...
}
Configure
and ConfigureServices
ConfigureServices
(optional):
Configure dependency injection.
Configure
:
Build pipeline by e.g. adding middlewares.
public void Configure(IApplicationBuilder app)
{
app.Use(async (context, next) => {
await context.Response.WriteAsync(">>> Hello ");
await next();
await context.Response.WriteAsync("World <<<");
});
app.Map("/beautiful", beautifulApp => beautifulApp.Run(
async context => await context.Response.WriteAsync("beautiful ")));
}
Note: Encapsulate complex logic in middleware
Details
Microsoft.AspNet.StaticFiles
dependencyConfigure
dnx web
(self-hosted)docker run -it -v ~/myApp:/src -p 80:5000 microsoft/aspnet /bin/bash
dnvm install 1.0.0-rc1-update1 -r coreclr
dnvm use 1.0.0-rc1-update1 -r mono
dnu restore
dnvm use 1.0.0-rc1-update1 -r coreclr
dnx web
Control environment with environment variables
Can be done directly in VS
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
// Running in development mode
app.UseDeveloperExceptionPage();
app.UseRuntimeInfoPage();
}
app.Use(async (context, next) =>
{
if (context.Request.Query.ContainsKey("exception"))
{
throw new InvalidOperationException("Something bad happened ...");
}
await next();
});
...
}
No web.config
anymore
Key/value pair settings from different providers
E.g. memory, environment variables, JSON, INI, XML
Extensible
Details about writing custom providers
Options pattern for DI integration
Support for logging built into ASP.NET Core
Various logger built in
E.g. console, NLog
Support for DI built into ASP.NET Core
Details about DI
Framework-provided services and your own services
Default container can be replaced
Details
public void ConfigureServices(IServiceCollection services)
{
...
// My own service
services.AddSingleton(typeof(INameGenerator), typeof(NameGenerator));
...
// Framework services
services.AddApplicationInsightsTelemetry(configuration);
services.AddCors();
services.AddMvc();
...
}
public void ConfigureServices(IServiceCollection services)
{
services.AddSingleton<MySingletonService>();
services.AddTransient<MyTransientService>();
services.AddScoped<MyScopedService>();
services.AddMvc();
}
Build end-to-end sample app with server and client components
DNX supports/will support multiple test frameworks
Current, XUnit is preferred
Used to MSTest but new to XUnit? Compare ...
Create global.json
referencing projects
{
"projects":[
"src/client",
"src/math-library",
"test/lib-test"
]
}
project.json
{
"dependencies": {
"xunit": "2.1.0",
"xunit.runner.dnx": "2.1.0-rc1-build204",
"math-library": ""
},
"frameworks": {
"dnxcore50": {}
},
"commands": {
"test": "xunit.runner.dnx"
}
}
using Xunit;
namespace Tests
{
public class TestClass
{
[Fact]
public void TestAdd()
{
Assert.Equal(2, Library.Math.Add(1, 1));
}
...
}
}
dnx test
Roslyn Scripting API for C#
Finally back ;-)
{
"dependencies": {
...
"Microsoft.CodeAnalysis.CSharp.Scripting": "1.1.1"
}, ...
}
csi.exe
for running C# scripts in dev command prompt
C# Interactive Windows in VS
VS2015 Update 1 can run tests in parallel on multi-core
Must be separate assemblies, distinct processes
<?xml version='1.0' encoding='utf-8'?>
<RunSettings>
<RunConfiguration>
<MaxCpuCount>8</MaxCpuCount>
</RunConfiguration>
</RunSettings>
See you next SNEK!