C#

Set up continuous integration for .NET Core with OpenShift Pipelines

Set up continuous integration for .NET Core with OpenShift Pipelines

Have you ever wanted to set up continuous integration (CI) for .NET Core in a cloud-native way, but you didn’t know where to start? This article provides an overview, examples, and suggestions for developers who want to get started setting up a functioning cloud-native CI system for .NET Core.

We will use the new Red Hat OpenShift Pipelines feature to implement .NET Core CI. OpenShift Pipelines are based on the open source Tekton project. OpenShift Pipelines provide a cloud-native way to define a pipeline to build, test, deploy, and roll out your applications in a continuous integration workflow.

In this article, you will learn how to:

  1. Set up a simple .NET Core application.
  2. Install OpenShift Pipelines on Red Hat OpenShift.
  3. Create a simple pipeline manually.
  4. Create a Source-to-Image (S2I)-based pipeline.

Continue reading “Set up continuous integration for .NET Core with OpenShift Pipelines”

Share
Using OpenAPI with .NET Core

Using OpenAPI with .NET Core

In this article, we’ll look at using OpenAPI with .NET Core. OpenAPI is a specification for describing RESTful APIs. First, I’ll show you how to use OpenAPI to describe the APIs provided by an ASP.NET Core service. Then, we’ll use the API description to generate a strongly-typed client to use the web service with C#.

Writing OpenAPI descriptions

Developers use the OpenAPI specification to describe RESTful APIs. We can then use OpenAPI descriptions to generate a strongly-typed client library that is capable of accessing the APIs.

Note: Swagger is sometimes used synonymously with OpenAPI. It refers to a widely used toolset for working with the OpenAPI specification.

Continue reading “Using OpenAPI with .NET Core”

Share
How to fix .NET Core’s ‘Unable to obtain lock file access’ error on Red Hat OpenShift

How to fix .NET Core’s ‘Unable to obtain lock file access’ error on Red Hat OpenShift

Well, it finally happened. Despite the added assurances of working with containers and Kubernetes, the old “It works on my machine” scenario reared its ugly head in my .NET Core (C#) code. The image that I created worked fine on my local PC—a Fedora 32 machine—but it crashed when I tried running it in my Red Hat OpenShift cluster.

The error was “Unable to obtain lock file access on /tmp/NuGetScratch.” Let’s take a quick look at what happened, and then I’ll explain how I fixed it.

Identity issues

After a lot of web searching and a discussion with a Red Hat .NET Core engineer, I discovered the underlying problem. It turns out that within a container, the identity used to initially run the program (using the dotnet run command) must be the same for subsequent users.

The problem might be easy to understand, but what’s the solution?

Continue reading “How to fix .NET Core’s ‘Unable to obtain lock file access’ error on Red Hat OpenShift”

Share
C# 8 nullable reference types

C# 8 nullable reference types

In the previous article, we discussed C# 8 default interface methods. In this article, we’ll look at C# 8 nullable reference types. Reference types refer to an object that is on the heap. When there is no object to refer to, the value is null. Sometimes null is an acceptable value, but often it is an illegal value that leads to ArgumentNullExceptions and NullReferenceExceptions.

C# 8 finally gives us the ability to express whether a variable shouldn’t be null, and when it can be null. Based on these annotations, the compiler will warn you when you are potentially using a null reference, or passing a null reference to a function that won’t accept it.

Continue reading “C# 8 nullable reference types”

Share
C# 8 default interface methods

C# 8 default interface methods

In the previous articles, we discussed C# 8 async streams and pattern matching. In this article, we’ll look at C# 8 default interface methods.

Extending interfaces

Before C# 8, it was not possible to add members to an interface without breaking the classes that implement the interface. Because interface members were abstract, classes needed to provide an implementation. C# 8 allows us to extend an interface and provide a default implementation. The runtime (which also needs to support this feature) uses the default implementation when the class does not provide it:

interface IOutput
{
    void PrintMessage(string message);
    void PrintException(Exception exception)
        => PrintMessage($"Exception: {exception}");
}
class ConsoleOutput : IOutput
{
    public void PrintMessage(string message)
        => Console.WriteLine(message);
}

In this example, ConsoleOutput does not provide an implementation for PrintException. When PrintException is called against a ConsoleOutput instance, the default method from the IOutput interface will be called. ConsoleOutput might provide its own implementation.

Continue reading “C# 8 default interface methods”

Share
C# 8 asynchronous streams

C# 8 asynchronous streams

.NET Core 3.1 (December 2019) includes support for C# 8, a new major
version of the C# programming language. In this series of articles, we’ll look at the new features in .NET’s main programming language. This first article, in particular, looks at asynchronous streams. This feature makes it easy to create and consume asynchronous enumerables, so before getting into the new feature, you first need to understand the IEnumerable interface.

Note: C# 8 can be used with the .NET Core 3.1 SDK, which is available on Red Hat Enterprise Linux, Fedora, Windows, macOS, and on other Linux distributions.

A brief history of IEnumerable

The classic IEnumerable<T> has been around since .NET Framework 2 (2005). This interface provides us with a type-safe way to iterate over any collection.

The iteration is based on the IEnumerator<T> type:

Continue reading “C# 8 asynchronous streams”

Share
Using .NET PInvoke for Linux system functions

Using .NET PInvoke for Linux system functions

If you’ve developed Windows applications with .NET, you may have found yourself in a situation where the framework did not provide the APIs you needed. When that happens, you first need to identify the system APIs and then make them available using PInvoke. A website like pinvoke.net provides copy-and-pasteable code snippets for many Win32 API functions.

.NET Platform Invoke (PInvoke) makes it easy to consume native libraries. In this article, we’ll take a look at using PInvoke for Linux system functions.

Continue reading “Using .NET PInvoke for Linux system functions”

Share
Using Kubernetes readiness and liveness probes for health checks with ASP.NET Core 2.2 on OpenShift

Using Kubernetes readiness and liveness probes for health checks with ASP.NET Core 2.2 on OpenShift

.NET Core 2.2 has been released. You can try it on Red Hat Enterprise Linux (RHEL) and OpenShift. One of the new features of ASP.NET Core is the Health Checks API.

In this article, which was written for C# Advent Calendar 2018, I show an example of how the API works with OpenShift by implementing two health checks for the Kubernetes liveness and readiness probes. Since OpenShift includes Kubernetes, this example also works well with Kubernetes.

Continue reading “Using Kubernetes readiness and liveness probes for health checks with ASP.NET Core 2.2 on OpenShift”

Share