Skip to main content

Posts

Showing posts from September, 2021

C# 10 - Implicit (global) usings

Yesterday I thought that my journey in discovering possibilities of the ‘using’ keyword had ended, but further reading introduced me to a new .NET 6 feature: implicit (global) using directives . You can enable this feature by adding a <ImplicitUsings>enable</ImplicitUsings> setting inside a <PropertyGroup> in your .csproj file. Remark: The project templates in the .NET 6 SDK include this setting by default Enabling this feature will automatically generate a global usings file for you. You can see the generated file by looking inside the obj folder that gets created when you build a project. In here you'll find a subfolder named for your build configuration(e.g. Debug, Release, ...) containing a net6.0 folder. Inside there you'll find a file called something like ExampleApp.GlobalUsings.g.cs. The content of this file will look something like this: The set of included namespaces changes according to the project type. You can control what is gen...

C# 10–Global using

I continue my journey in discovering possibilities of the ‘using’ keyword and arrive at an upcoming feature in C# 10: global using directives . C# 10.0 allows you to define using directives globally, so that you don’t have to write them in every file. Let’s take a look at a simple example. I created a GlobalUsings.cs class in my project and added the following 2 lines: By doing this the 2 namespaces above are available in every C# file in my project. Remark: In this example I’ve put my global usings in a seperate file. This isn’t necessary, you can put the global usings in any code file, although I would recommend isolating it to make them easier to discover and maintain. Now I can simplify my Program.cs file: You can combine this feature with the using static as well: This allows me to even further simplify my Program.cs file: More information: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive#global-modifier

C#–Using static

While writing my blog post yesterday about class aliases , I was reading through the documentation about the using keyword and noticed another feature I almost forgot: ‘using static’ . Through ‘using static’ you can import static members of types directly into the current scope . This can safe you from some extra typing work if you need a specific static class over and over again. An example: In the code above I have to repeat the ‘Console’ static class for each call. Now let’s rewrite this example with the help of ‘using static’ : More information: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/using-directive#static-modifier

Confuse your colleagues by using class aliases in C#

C# supports the concept of namespaces aliases for a long time. This allows you to create an alias for long namespaces so you don’t have to specify the whole name every time. An example: Did you know that this does not only work for namespaces but also for classes? It is also possible to alias a specific class name. An example: This feature could be fun if you start using aliases that match with class names used somewhere else in your codebase. Like in the example above where I assigned the Product class an Order alias. Can’t be any more confusing! So please don’t do this at work and choose a good alias name instead…

Learning the ins and outs of web development through web.dev

If you are new to web development or want to further expand your web development skills , go check out all the learning material provided at web.dev . At the moment of writing this post, you can find courses about CSS, performance, web frameworks, and much more…

Azure DevOps–Export wiki to PDF

If you ever want to export your Azure DevOps wiki, you can use the AzureDevOps.WikiPDFExport tool. Start by cloning your Azure DevOps wiki to a local folder. After doing that download the latest release of the AzureDevOps.WikiPDFExpert tool here: https://github.com/MaxMelcher/AzureDevOps.WikiPDFExport/releases Copy the file to the root of the wiki repository. Now you can execute the tool and a PDF file called Export.pdf should be generated Troubleshooting While executing the tool I encountered some issues so here are some troubleshooting tips. Tip 1 – Ignore the Qt: Could not initialize OLE (error 80010106) warning If you see a Qt: Could not initialize OLE (error 80010106) warning while executing the tool, don’t worry. You can just ignore this message. Tip 2 – Be aware about the .order file The first time I executed the tool only a few of my wiki pages were included. I found out that this was the case because when it detects a .order file it will only...

ASP.NET Core: Share a cookie between subdomains

By default when you create a cookie in ASP.NET Core it is only applicable to that specific subdomain. For example, a cookie created in subdomain.mydomain.com can not be shared with a second subdomain secondsubdomain.mydomain.com . To change this behavior,  you need to add the following code in Startup.ConfigureServices : By specifying a common domain in the Cookie.Domain property, the cookie will be shared between subdomain.mydomain.com and secondsubdomain.mydomain.com.

Azure App Service Health check

Azure App Service has a built-in health check feature. Through this feature Azure can automatically check the health endpoint of your web app and can take an unhealthy instance out of the load balancer until it's healthy again, or even restart or replace it. To enable Health check, browse to the Azure portal and select your App Service app. Under Monitoring , select Health check . Select Enable and provide a valid URL path on your application, such as /hc or /api/health . Click Save . Remark: Notice the Load balancing slider. Here you can specify the time an app can be unhealthy before being removed from the load balancer. Azure only looks at the HTTP response the page gives. If the response is in the 2XX range the instance is considered healthy, else it is shown as degraded or unhealthy. It also doesn't follow redirects. If your webapp settings allow http the check by Azure is done over http. If it is set to HTTPS only then Azure used https calls to check th...

Model binding in ASP.NET Core

While converting an existing ASP.NET MVC application to ASP.NET Core I noticed it was using a custom model binder. That made me wonder how I could achieve the same thing in ASP.NET Core. In ASP.NET MVC a model binder had to implement the IModelBinder interface: To use the model binder you had to let the ASP.NET MVC framework know the existence of the custom model binder. In the original codebase we were using Unity and we created a small extension method that allowed us to register the Modelbinder: That extension method allowed us to write the following code: Let’s find out how to achieve the same result in ASP.NET Core… In ASP.NET Core you should also implement a IModelBinder interface, although the contract is different(and async): To use this custom model binder you can either create a custom ModelBinderProvider or use the ModelBinder attribute: More information: Custom Model Binding in ASP.NET Core

Visual Studio Code–Draw.io extension

While pair programming with a colleague I noticed he was using  draw.io directly inside Visual Studio Code. This was made possible by the following extension: https://marketplace.visualstudio.com/items?itemName=hediet.vscode-drawio It offers some great features like: Using draw.io offline Work together on a diagram using the liveshare feature of VS Code Link diagram elements to code fragments I’m a fan!

The ‘async void’ trap

A colleague contacted me that he had trouble using a library I created. This library is used to abstract away the used mailing system. He told me that when the mail couldn’t be send succesfully, the error message got lost and that the library doesn’t return anything useful. I started by running my integration test suite against this library(these are the moments you are extremely happy that you’ve spend so much time on writing tests) but all tests returned green. I’ll asked the colleague to send me the code he was using. Do you notice what’s wrong? The title of this post already gives you the answer. He was using ‘async void’ instead of ‘async Task’. ‘async void’ should only be used by event handlers. I recommended using AsyncFixer to avoid this kind of issues in the future.

Azure DevOps - User is not available

I got a question from a colleague who was asking how long it took before a user that was added to Azure AD is available in Azure DevOps. The answer is simple; instant. So why was this person asking this question then? The reason is that there is a difference in behavior depending if the user is already added to the Azure DevOps organisation or not. If the user is not part of the organisation yet, when you search for the user by firstname and lastname, nothing will be found. But if you search for the user by his email address, you will find the user. It is only after the user is added for the first time to an Azure DevOps organisation that you will be able to find a user by his name. Until then you should use the email address to search for the user in Azure AD.

MassTransit–Message Initializers

Let’s have a look at a small example that shows how to publish a message in MassTransit: What is maybe not immediatelly obvious in the code above, is that when you call publishEndpoint.Publish<OrderSubmitted> a lot of magic is going on. The generic argument would make you think that the  Publish method expeccts a message of type OrderSubmitted . But we are passing an anonymous object??? And to make it even stranger, we only have the OrderSubmitted interface, we never created a class that implements it??? What is happening? How this even works? The answer to all this magic are Message Initializers . When calling the Publish method above, you are using a specific overload: Task Publish<T>(object values, CancellationToken cancellationToken = default) where T : class; Message initializers make it easy to produce interface messages using anonymous objects. The message initializers will try to match the values of an anonymous object with the propertie...

C# switch expressions

A lot of the examples of switch expressions you can find are where a function directly maps to an expression. For example: This could make you think that you cannot use a switch expression inside a method body. It certainly is possible. The only important thing is that you assign the result of your switch expression to a variable. Let’s rewrite the example above:

Copy files through MSBuild

So far I’ve always used xcopy in a pre or post build event to copy files between projects: But did you know that you don’t need this and that it can be done by standard msbuild features? (By the way the code above doesn’t even work on Linux) To achieve the same thing you can use the following msbuild configuration in your csproj file: 2 important things to notice: You can use file patterns in the 'Include' to specify a set of files You can use ‘LinkBase’ to specify a target folder

Avoid concurrent test runs by using XUnit Collection Fixtures

Last week I blogged about XUnit Collection Fixtures . Something I wasn’t fully aware of but does make sense if you think about it is that by using the [Collection] attribute all tests that share the same context in the same thread. So you don’t need to worry about concurrent test runs. By default XUnit tests that are part of the same test class will not run in parallel. For example, in the code below Test1 and Test2 will never run at the same time: If you want to achieve the same behavior while having tests in multiple classes, you can put tests in the same collection:

Troubleshoot Kubernetes deployments

In case your deployments on Kubernetes fails, the following diagram can help: (It is created by the people from learnk8s who provide Kubernetes training) A PDF version of this diagram can be found here: https://learnk8s.io/a/a-visual-guide-on-troubleshooting-kubernetes-deployments/troubleshooting-kubernetes.v2.pdf

XUnit Collection fixtures

While reviewing some XUnit unit tests, I noticed the usage of the [Collection] attribute. I didn’t know the attribute. So I took a look at the XUnit documentation and discovered the existence of Collection fixtures. It allows you to create a single test context and share it among tests in several test classes, and have it cleaned up after all the tests in the test classes have finished. In the code I was reviewing it was used to spin up a test server and shut it down after all tests has been completed. I don’t find it very intuitive how it should be used but it is well explained in the documentation. In case you are too lazy to click on the link, here are the steps: Create the fixture class, and put the startup code in the fixture class constructor. If the fixture class needs to perform cleanup, implement IDisposable on the fixture class, and put the cleanup code in the Dispose() method. Create the collection definition class, decorating it with the [CollectionDef...

Azure Pipelines - Ubuntu 16.04 LTS environment is deprecated

When trying to run a release pipeline in Azure DevOps, the following warning started to appear for all our builds: Ubuntu 16.04 LTS environment is deprecated and will be removed on September 20, 2021. Migrate to ubuntu-latest instead. To get rid of this warning, we had to explicitly specify the vmImage property inside our YAML build template: More information: https://docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema%2Cparameter-schema#pool