Tải bản đầy đủ (.pdf) (69 trang)

transitioning to net core on red hat enterprise linux

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (2.71 MB, 69 trang )


Programming



Transitioning to .NET Core on Red Hat
Enterprise Linux
Don Schenck


Transitioning to .NET Core on Red Hat Enterprise Linux
by Don Schenck
Copyright © 2017 O’Reilly Media. All rights reserved.
Printed in the United States of America.
Published by O’Reilly Media, Inc., 1005 Gravenstein Highway North, Sebastopol, CA 95472.
O’Reilly books may be purchased for educational, business, or sales promotional use. Online
editions are also available for most titles ( For more information, contact
our corporate/institutional sales department: 800-998-9938 or
Editors: Nan Barber and Susan Conant
Production Editor: Melanie Yarbrough
Copyeditor: Gillian McGarvey
Proofreader: Jasmine Kwityn
Interior Designer: David Futato
Cover Designer: Karen Montgomery
Illustrator: Rebecca Demarest
September 2016: First Edition
Revision History for the First Edition
2016-09-20: First Release
2016-10-21: Second Release
2016-12-06: Third Release
The O’Reilly logo is a registered trademark of O’Reilly Media, Inc. Transitioning to .NET Core on


Red Hat Enterprise Linux, the cover image, and related trade dress are trademarks of O’Reilly
Media, Inc.
While the publisher and the author have used good faith efforts to ensure that the information and
instructions contained in this work are accurate, the publisher and the author disclaim all
responsibility for errors or omissions, including without limitation responsibility for damages
resulting from the use of or reliance on this work. Use of the information and instructions contained in
this work is at your own risk. If any code samples or other technology this work contains or describes
is subject to open source licenses or the intellectual property rights of others, it is your responsibility


to ensure that your use thereof complies with such licenses and/or rights.
978-1-491-97055-3
[LSI]


What to Expect from This Book
This book is targeted at—but not limited to—.NET developers with any level of experience. Starting
with a basic “Hello World” console application, it moves along through ASP.NET, MVC, and Entity
Framework applications, eventually arriving at a full-featured application running in a Linux
container. Because the code in this book is limited to C#, your existing knowledge of .NET and C#
will largely determine the speed at which you progress through this volume. More experienced
developers will be interested in the few key differences when developing for Linux (and there are
quite a few), whereas beginning developers can use this book to learn more advanced programming
techniques—the fact that those techniques are related to .NET Core is just icing on the cake.
If you’ve spent most of your time writing code in a language other than C#, with Linux as your native
operating system, don’t fret. Though knowledge of C# is highly recommended, even a novice
developer with a desire to learn can use this volume, perhaps in concert with another manual that
guides the reader in C# development.

Some Assumptions

This book assumes some previous experience with the .NET Framework. Again, while it’s
technically not necessary to have prior knowledge when you begin reading, you will need to be
familiar with .NET (either by experience or education) to understand what’s happening. Again, not to
worry—the knowledge needed isn’t as deep as you might fear. Grasp a few key concepts and you’ll
be good to go.
For the purposes of simplicity, the Linux distribution used in the examples will be Red Hat Enterprise
Linux (RHEL). Any adjustments necessary for other Linux distributions will be pointed out as we go.

Your Environment
To follow along with the narrative and code, you need to install the Red Hat Container Development
Kit (CDK) and clone or download a repository from GitHub. Step-by-step instructions are provided
in Chapter 1.

Formatting
The following typographical conventions are used in this book:
Text will be in the typeface you are reading now.
// Code is formatted like this:


using System;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World!");
}
}
}

Command-line commands will be shown like this

Italic
Indicates new terms, URLs, email addresses, filenames, and file extensions.
Constant width
Used for program listings, as well as within paragraphs to refer to program elements such as
variable or function names, databases, data types, environment variables, statements, and
keywords.
Constant width bold
Shows commands or other text that should be typed literally by the user.
Constant width italic
Shows text that should be replaced with user-supplied values or by values determined by context.

TIP
This element signifies a tip or suggestion.

NOTE
This element signifies a general note.

WARNING
This element indicates a warning or caution.


.NET Core Is the Future
In November 2014, Microsoft announced that the .NET Framework would be transitioned to an open
source development model. This announcement was met with surprise and open arms by the .NET
community. Although Microsoft had, up to that moment, done an admirable job of soliciting input from
developers about .NET features and bugs, making the source available meant a much higher level of
engagement. The standard open source model of using a GitHub repo—with issues, milestones, pull
requests, and the related discussions—meant that anyone, anywhere could have instant and

transparent access to the development team. Developers could participate in discussions and research
defects and workarounds. Schedules and roadmaps would now be available to everyone, leading to
more realistic expectations. Surprise announcements would give way to planned milestones.
Meanwhile, developers outside the .NET world saw this as an opportunity to bring their open source
experience and knowledge to one of the more pervasive software development platforms. The free
exchange of ideas, code reviews, and sense of community found its place inside the Microsoft-centric
developer’s world. The infusion of non-.NET developers meant that “dot netters” could gain a
broader view of development in general. This is a very good thing.
This is the new model. This is the future.
.NET Core is not just another .NET Framework. Rather, it is the future of .NET. Microsoft has stated
that the previous framework, 4.6.1, will still be supported, and bug fixes will be applied, but any new
.NET features will be reserved for .NET Core. Using .NET Core as your basis for future work is in
line with Microsoft’s stated intentions. While migrating existing code to .NET Core may or may not
be a good idea, future development should be based on .NET Core if possible. In short, this is the
.NET Framework. Period. Full stop.

What’s Missing
Because some parts of .NET are either specific to Windows or outdated, not everything made the
journey from proprietary software to the open source model and .NET Core 1.0.
Here’s a list of some of the things that didn’t make the transition:
MWF (Windows Forms)
Web forms
WCF (SOAP)
In addition, some things haven’t been ported yet—perhaps the biggest being SignalR. Microsoft has
publicly stated that SignalR will be ported to .NET Core.

NOTE


From this point on, unless the difference is worth noting, references to .NET CoreCLR, CoreFX, and the like, will be

simplified to “.NET”.

What’s New
.NET is more modular now, which is a definite benefit from starting over when designing the
framework. Parts that were previously included by default are now excluded by default. Even what
may seem to be the most basic items, such as the ability to render static files in an ASP.NET page, are
now optional. This means that you need to be more expressive in your coding, but it also results in
performance improvements. The trade-off is worth the cost: writing code is easier than optimizing
code.


Chapter 1. Setting Up Your Environment
This chapter will guide you through setting up the environment used in the examples in this book. It
includes a Linux Virtual Machine (VM) running on a Windows 10 machine, and a clone or download
of a GitHub repository (repo). The VM in this setup will use the Red Hat Container Development Kit
(CDK), which includes an image of Red Hat Enterprise Linux (RHEL), Oracle’s Virtual Box, and
Vagrant.

Your Red Hat Account
Before you can download the RHEL image and the CDK, you need to register at the Red Hat
Developer website. This is free; all you need is an email address and a password. You can opt out of
the Red Hat Developers newsletter if you wish, but I suggest keeping it—at least initially.
This gives you access to all the tools and help, including the CDK (with RHEL), forums, knowledge
base, and more.
Keep your username and password handy; you’ll need them every time you start your VM in order to
register with Red Hat and enable your subscription.

Installing the CDK
The Red Hat CDK includes a copy of RHEL 7 that’s been preloaded with the docker command and
OpenShift. It runs the RHEL VM using Vagrant and Virtual Box. Fortunately, if you’re not familiar

with these technologies, the CDK makes the process of installing them transparent. Basically, you
download, install, and run.
Once you’ve registered and logged in, select the TECHNOLOGIES menu and the Red Hat Container
Development Kit option, as shown in Figure 1-1.


Figure 1-1. Select Red Hat Container Development Kit

This takes you to the Container Development Kit page.
At the top, click the GET STARTED button to reveal your choice of Windows or Mac/Linux assets.
From there, simply follow the screen prompts to download the CDK, as shown in Figure 1-2.


Figure 1-2. Container Development Kit download page

After the CDK installer is downloaded (the installer is development-suite-1.0.0-GA-bundleinstaller.exe, which is about 1.4 GB in size), open it and follow the prompts to install the CDK on
your Windows machine. You’ll need your Red Hat username and password to get started, as you can
see in Figure 1-3.

Figure 1-3. Sign in to start the CDK installation


Disable Hyper-V
Before you can use Vagrant, you’ll need to disable Hyper-V on your Windows machine. Use the
Windows Features Control Panel applet to do this, as shown in Figure 1-4.

Figure 1-4. Disable Hyper-V

If you need to switch between enabling and disabling Hyper-V, there’s a helpful guide at Scott
Hanselman’s blog.


Start Your VM
Now that you’ve installed everything, you can start the VM. Assuming that you used the default values
during the installation, open a command prompt, navigate to the proper folder, and launch the VM
using the vagrant up command:
PS C:\DevelopmentSuite\cdk\components\rhel\rhel-ose> vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
==> default: Clearing any previously set forwarded ports...
==> default: Clearing any previously set network interfaces...
==> default: Preparing network interfaces based on configurat...
default: Adapter 1: nat
default: Adapter 2: hostonly
==> default: Forwarding ports...
default: 22 => 2222 (adapter 1)
==> default: Running 'pre-boot' VM customizations...
==> default: Booting VM...
==> default: Waiting for machine to boot. This may take a few...
default: SSH address: 127.0.0.1:2222
default: SSH username: vagrant


default: SSH auth method: password
default: Warning: Connection timeout. Retrying...
default: Warning: Remote connection disconnect. Retrying...
==> default: Machine booted and ready!
==> default: Registering box with vagrant-registration...
default: Would you like to register the system now (defau...
​ default: username: **redacted**
default: password:
[default] GuestAdditions 5.0.26 running --- OK.

==> default: Checking for guest additions in VM...
==> default: Configuring and enabling network interfaces...
==> default: Copying TLS certificates to C:/DevelopmentSuite/...
==> default: Rsyncing folder: /cygdrive/c/DevelopmentSuite/cdk/...
==> default: Mounting SMB shared folders...
default: C:/shared => /shared
==> default: Machine already provisioned. Run `vagrant provis...
==> default: flag to force provisioning. Provisioners marked...
==> default: Running provisioner: shell...
default: Running: inline script
==> default: Running provisioner: shell...
default: Running: inline script
==> default:
==> default: Successfully started and provisioned VM with 2...
==> default: To modify the number of cores and/or available...
==> default: VM_CPU respectively VM_MEMORY.
==> default: You can now access the OpenShift console on: https...
==> default:
==> default: To use OpenShift CLI, run:
==> default: $ vagrant ssh
==> default: $ oc login 10.1.2.2:8443
==> default:
==> default: Configured users are (<username>/):
==> default: openshift-dev/devel
==> default: admin/admin
==> default:
==> default: If you have the oc client library on your host,...
PS C:\DevelopmentSuite\cdk\components\rhel\rhel-ose>

RUN AS ADMINISTRATOR

Get in the habit of opening the command prompt—I suggest using PowerShell—by using the “Run as Administrator” option
because you’ll need administrator privileges later when you are editing and debugging from Windows.

Now you can use ssh to get into the VM. The easiest option is to use the vagrant ssh command, which
will open an ssh session inside the VM, as shown in Figure 1-5.

Figure 1-5. Using vagrant SSH to start a bash session on the VM

At this point, the VM is set up and running and you’re ready to begin your transition to .NET on Linux.


Getting the Source Code
Once you are inside the VM, you can go ahead and fetch the source code associated with this book.
You can do this by running the following command:
git clone />
You’ll now have a directory, NetOnLinuxBook, that contains subdirectories for this book.

NOTE
When applicable, at the beginning of each chapter, you will see a note directing you to the source code from the repo that is
associated with that chapter.


Chapter 2. Getting Started: From Zero to
“Hello World” in One Chapter
From Zero to “Hello World” in One Chapter
One of the benefits of .NET Core is the ability to get a simple console application up and running in a
matter of seconds. While more complex applications require a deeper understanding of the
framework and the language (C#, in our case), the building and execution of a simple “Hello World”
application can be done with very little effort. This chapter will get you up and running in one quick
session.


ASSOCIATED SOURCE CODE
The source code can be found in the /NetOnLinuxBook/HelloWorld/ directory.

Overview of .NET
When Microsoft introduced the .NET Framework in 2002, it marked a new era in software
development for Microsoft-centric developers. The move marked a shift in thinking, allowing
Windows Forms developers to create websites in a way that was somewhat familiar. Dragging text
areas and buttons onto a form and adding code-behind code made the transition almost seamless, if
somewhat unconventional. In fact, it was sometimes referred to as “Windows for the Web.”
Fast-forward 12 years, and Microsoft announces that .NET will be open source. It now supports
MVC, ORM, CSS, and every other TLA (three-letter acronym) one can imagine.
What happened?
In short, as has been said, “Open source won.”
With the fight over, Microsoft has pivoted quickly and is now releasing pieces of the .NET
framework at a much faster pace, with thousands of developers from all over the world contributing.
In November 2015, when Microsoft and Red Hat announced a partnership (to replace an adversarial
relationship), it became clear that .NET was not only moving into the world of open source but that
being able to run .NET programs on Linux—with the full blessings and support of Microsoft and Red
Hat—was actually going to happen.
And that’s where we find ourselves today, with both Microsoft and Red Hat embracing Linux and
.NET. As a developer, you have the opportunity to widen your skillset and marketplace. There’s no
reason to wait, as both .NET and Red Hat Enterprise Linux (RHEL) can be obtained at no cost. It’s


time to get started.

Installing .NET
Installing the framework is easier and quicker than ever; that’s because it’s been separated into small
layers. It’s helpful to understand these layers of .NET. Each layer exists separately from the other and

evolves at a different pace. Each has a separate code base and GitHub repo, as shown in Figure 2-1.

Figure 2-1. The layers of the new world of .NET

.NET CLR
This is where the Common Language Runtime (CoreCLR) lives. It includes the garbage collector, the
Just-In-Time (JIT) compiler, base data types, and some low-level classes.

.NET CoreFX
The System.* and Microsoft.* libraries that run on .NET Core and enable you to run your
applications. When you type using System.<foo> in your program, you are accessing the libraries at
this level. CoreFX includes classes for collections (System.Collections), filesystems (System.IO),
XML (System.Xml), asynchronous processing (System.Threading), and more. You can see the entire
list of libraries at the GitHub repo. At this level, basic console applications (such as the ubiquitous
“Hello World” app) can run.


.NET CLI
The command-line interface, which allows you to build and launch your applications. Compiling
programs, pulling NuGet packages, running tests, running your applications—all these tasks use the
dotnet CLI. As a developer, you’ll likely spend a great deal of time here or use an IDE that leverages
the CLI.

ASP.NET Core
These are the libraries that allow you to write web services and websites. Because it is totally
modular, ASP.NET Core allows you to include only the pieces you need—for example, running a
static website—while excluding the bits you don’t need. This reduces size, increases performance,
and makes deployment faster.

Tooling

Any tools that make your life easier as a developer—whether they are a part of Visual Studio or
Visual Studio Code, or other tools (such as yeoman)—reside at this level. This level is not only
optional, but tools may or may not be available depending on your operating system and toolset.
Whereas in the beginning, .NET development tools from Microsoft were tightly coupled with the
framework and Visual Studio, now they are totally separate (this has actually been the case since
2008).

HELP, I DON’T REALLY KNOW LINUX THAT WELL!
New to Linux? That’s OK; we all were at one point in our lives. Don’t fret—you can download a free Linux Cheat Sheet
at the Red Hat Developer’s website.

Installation Instructions
Assuming you have a Red Hat Enterprise Linux 7 subscription, follow these instructions to install
.NET Core. Note that you will need administrator privileges to perform the installation:
sudo subscription-manager list --available

This displays a list of all available subscriptions. Near the end of the listing, a Pool ID is revealed,
as in this example output shown in Figure 2-2.


Figure 2-2. subscription-manager list --available output showing Pool ID

Using the Pool ID, run the following command:
sudo subscription-manager attach --pool=<Pool ID>

Now you can enable the package and perform the installation:
sudo subscription-manager repos
--enable=rhel-7-server-dotnet-rpms
sudo yum install -y scl-utils
sudo yum install -y rh-dotnetcore10


Finally, to make the framework available to your command line, use the following command, which
will enable the framework in a new bash session:
sudo scl enable rh-dotnetcore10 bash

Every time you open a bash session in the VM, you’ll need to run the this command. Not only is this a
nuisance, but it won’t work if you wish to debug your code from within Visual Studio. To avoid this
issue, add the following line to the file ~/.bashrc in your VM:
source scl_source enable rh-dotnetcore10

This will download and install the latest RHEL-approved .NET Core distribution and make it
available. You can verify your installation (and see what version you are using) by using the version
command:
dotnet --version

Other Linux Distros
The easiest way to install on other distros is to visit the .NET website and follow the screen prompts.
WHAT IF I DON’T HAVE RHEL?
If you don’t have a machine running RHEL, or if you’d like to create a Virtual Machine on your


Windows machine and use it to run RHEL (I strongly recommend this route), visit the Red Hat
.NET website and follow the prompts to download and install RHEL. While you’re at it, I
recommend grabbing and installing the Container Development Kit (CDK). You can use it later
when working with Linux containers.

Keeping Current
To keep up to date with the progress of .NET, visit the project current release page on GitHub.

Your First .NET Application on Linux

Be prepared to be underwhelmed. Creating your first .NET application, the standard “Hello World”
application, on Linux involves only three steps (five if you include creating a directory and moving
into it).
Actually, the creation of the source code is only one command:
mkdir helloworld
cd helloworld
dotnet new
dotnet restore
dotnet run

Putting it all together should yield something like the following (the output is included in this snippet):
$ mkdir hw
$ cd hw
$ dotnet new
Created new C# project in /home/vagrant/src/hw.
$ dotnet restore
log : Restoring packages for /home/vagrant/src/hw/project.j...
log : Writing lock file to disk.
Path: /home/vagrant/src/hw/project.lock.json
log : /home/vagrant/src/hw/project.json
log : Restore completed in 809ms.
$ dotnet run
Project hw (.NETCoreApp,Version=v1.0) will be compiled because
expected outputs are missing
Compiling hw for .NETCoreApp,Version=v1.0
Compilation succeeded.
0 Warning(s)
0 Error(s)
Time elapsed 00:00:01.0233055
Hello World!

$

OTHER LANGUAGES


Microsoft has promised that support for F# and Visual Basic is coming. In fact, you can go ahead and run dotnet new -lang F# now and see what happens.

We’ll cover the commands later, but first let’s take a look at what was generated by the dotnet new
command:
$ ls -l
total 8
-rwxrw-r--. 1 vagrant vagrant 202 Jun 15 14:43 Program.cs
-rwxrw-r--. 1 vagrant vagrant 348 Jun 15 14:43 project.json
$

What just happened? Where did this code come from, what does it look like, and why doesn’t your
directory look like this? We’ll cover that in Chapter 3.


Chapter 3. Diving into the “Hello World”
Application
In Chapter 1, we installed .NET and easily created, built, and ran the “Hello World” application.
Let’s take a look at what happened when we built and ran our “Hello World” application (although
you and I both know you’ve already looked inside all the generated files).

ASSOCIATED SOURCE CODE
The source code can be found in the /NetOnLinuxBook/HelloWorld/.

We started by running the dotnet new command. Confession time: in fact, we skipped a command.
After running dotnet restore, you can run the dotnet build command to build the binary output. We

skipped it in the interest of brevity, and in fact when you execute dotnet run, the command will check
to see if a new build is required and run the build automatically. We’ll cover dotnet build later in this
chapter.

The dotnet new Command
The dotnet new command will create a new .NET project with the minimum amount of code and
associated files necessary to run the application. When run without any additional options, it will
create the “Hello World” console application. In this case, two files are created—Program.cs and
project.json:
$ ls -altr
total 8
-rwxrw-r--. 1 vagrant vagrant 348 Jun 15 14:43 project.json
-rwxrw-r--. 1 vagrant vagrant 202 Jun 15 14:43 Program.cs
drwxrwxr-x. 3 vagrant vagrant 23 Jul 8 11:24 ..
drwxrwxr-x. 2 vagrant vagrant 42 Jul 8 11:25 .

Program.cs is the program, and it’s short and sweet:
using System;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
Console.WriteLine("Hello World");


}
}
}


The result is obvious; an app that writes “Hello World” to the console.
Just for fun, let’s change it to say “Hello from Linux” (or whatever you please), then run the dotnet run
command again:
$ dotnet run
Project hw (.NETCoreApp,Version=v1.0) will be compiled because
​ inputs were modified
Compiling hw for .NETCoreApp,Version=v1.0Compilation succeeded.
0 Warning(s)
0 Error(s)
Time elapsed 00:00:00.8371978
Hello from Linux
$

Notice the message from the compiler. Even though we requested the program to run and didn’t
specifically ask for a compile, the dotnet CLI recognized the change in the source code1 and
automatically invoked the compiler (i.e., dotnet build). If you run dotnet build now, you’ll see that the
compile is not done.
Then why use dotnet build at all? Because you need it in your continuous integration/continuous
deployment (CI/CD) pipeline.

The dotnet restore Command
After we ran dotnet new, we used the dotnet restore command. What does that do?
It’s a package manager, similar to how one would use npm when working in Node.js, or pip when
working in Python.
The dotnet restore command pulls the dependency libraries, which are listed in the file project.json,
from the configured repository. In fact, the location is found inside the file
~/.nuget/NuGet/NuGet.Config. This file is created the first time you run the dotnet restore command.
You can edit the NuGet.Config file, adding your own repositories if you wish. For example, you may
have a repository of company-standard libraries stored within your local network or a remote server

(i.e., the cloud). Likewise, you can remove the reference to NuGet.org. Additionally, if you want to
live on the bleeding edge, you can use the NuGet.Config file to access daily builds in MyGet.org.
In addition to the default NuGet.Config file location, the restore command will automatically use a
NuGet.Config file that is in your project’s root directory. For example, if your project is in the
directory ~/src/web, and you have a file ~/src/web/NuGet.Config, it will automatically be used. It
will also be given priority over the default NuGet.Config file.


Finally, you can specify a NuGet.Config file at any location by using the --configfile option of the
dotnet restore command. When you do this, be aware that the default configuration file is not used.

What Gets Restored?
A look inside the file project.json reveals which libraries are restored when running dotnet restore.
In our case, there are no libraries listed, so none need to be restored:
{
"version": "1.0.0-*",
"buildOptions": {
"debugType": "portable",
"emitEntryPoint": true
},
"dependencies": {},
"frameworks": {
"netcoreapp1.0": {
"dependencies": {
"Microsoft.NETCore.App": {
"type": "platform",
"version": "1.0.0"
}
},
"imports": "dnxcore50"

}
}
}

(The other sections of the project.json file will be discussed later.)
Compare the previous section to the following partial dependencies section of a project.json that
requires several dependencies:
"dependencies": {
"Microsoft.AspNetCore.Authentication.Cookies": "1.0.0-*",
"Microsoft.AspNetCore.Authentication.Facebook": "1.0.0-*",
"Microsoft.AspNetCore.Authentication.Google": "1.0.0-*",
"Microsoft.AspNetCore.Authentication.MicrosoftAccount":
"1.0.0-*",
"Microsoft.AspNetCore.Authentication.OpenIdConnect": "1.0.0-*",
"Microsoft.AspNetCore.Authentication.Twitter": "1.0.0-*",
"Microsoft.AspNetCore.Diagnostics": "1.0.0-*",
"Microsoft.AspNetCore.Diagnostics.EntityFrameworkCore":
"1.0.0-*",
"Microsoft.AspNetCore.Http.Abstractions":"1.0.0-*",
"Microsoft.AspNetCore.Identity.EntityFrameworkCore": "1.0.0-*",
"Microsoft.AspNetCore.Mvc": "1.0.0-*",
"Microsoft.AspNetCore.Mvc.TagHelpers": "1.0.0-*",
"Microsoft.AspNetCore.Server.IISIntegration": "1.0.0-*",
"Microsoft.AspNetCore.Server.Kestrel": "1.0.0-*",
"Microsoft.EntityFrameworkCore.SqlServer": "1.0.0-*",
},


×