Wednesday, December 9, 2020

ASP.NET Core–Use dynamic proxy with standard dependency injection - Async

Yesterday I blogged about using Castle.DynamicProxy to generate a proxy class and use AOP techniques for caching. The code I showed worked for synchronous method calls but fails when you want to proxy async method calls.

Let’s see how we can get this working for async…

Here is the async version of our repository:

We need an extra NuGet package:

dotnet add Castle.Core.AsyncInterceptor

Now we have to change our interceptor to call a second async interceptor:

Our extension method that triggers the proxy creation remains the same:

Our registration code should be extended to register the async interceptor as well:

Tuesday, December 8, 2020

ASP.NET Core–Use dynamic proxy with standard dependency injection

You don’t need to use a 3th party IoC container to use AOP(Aspect Oriented Programming) and the proxy pattern in ASP.NET Core. We’ll combine the power of Castle.DynamicProxy and the standard DI to make this possible.

Castle's dynamic proxies allows you to create proxies of abstract classes, interfaces and classes (only for virtual methods/properties).

Let’s create an example that caches the output of a repository call.

Here is the example repository that we want to proxy:

Now we first need to create an interceptor that intercepts the method calls and caches the response:

Let’s move on to the DI registration. We first need to create an extension method that triggers the proxy creation:

Almost there, as a last step we need to register everything:

Monday, December 7, 2020

Azure DevOps–Set git tag on build

I was using a custom build task to add a tag to a git commit after a successful release. Turns out that this is not necessary and that you can tag a build directly in Azure DevOps pipelines. This can be done in Get Sources:

There you have a Tag sources option where you can decide the tag that should be set:

Simple and useful!

Friday, December 4, 2020

.NET Core - Clear IMemoryCache

.NET Core gives you 2 options to use as cache data in memory. Either you use the System.Runtime.Caching/MemoryCache (NuGet package) or the Microsoft.Extensions.Caching.Memory/IMemoryCache. The latter is recommended over System.Runtime.Caching/MemoryCache because it's better integrated into ASP.NET Core. For example, IMemoryCache works natively with ASP.NET Core dependency injection. Use System.Runtime.Caching/MemoryCache only as a compatibility bridge when porting code from ASP.NET 4.x to ASP.NET Core.

The memory cache can be registered in ASP.NET Core through the AddMemoryCache extension method.

I was looking at a way to clear the cache. However I noticed there wasn’t an appropriate method available when I took a look at the IMemoryCache interface:

A search on the Internet brought me to the following suggested solution:

This is not a good idea because it will iterate over all keys. Why? Take a look at the following remark in the documentation:

Retrieving an enumerator for a MemoryCache instance is a resource-intensive and blocking operation. Therefore, the enumerator should not be used in production applications.

A better solution is to use the Compact method available on the MemoryCache instance:

Remark: This of course only works when your IMemoryCache implementation is based on the MemoryCache class.

Azure Durable Entities–The actor model in disguise

The Azure Functions ecosystem introduced a new member; durable entities also know as entity functions.

Durable entities behave like tiny services that communicate via messages. Each entity has a unique identity and an internal state (if it exists). In that way they are quite similar to actors in the actor model. (However there are some important differences in the way they are implemented compared to Orleans or Akka.net).

There are 2 ways to create entities:

  • The class-based syntax represents entities and operations as classes and methods. This syntax produces easily readable code and allows operations to be invoked in a type-checked manner through interfaces.
  • The function-based syntax is a lower-level interface that represents entities as functions. It provides precise control over how the entity operations are dispatched, and how the entity state is managed.

Let’s have a look at the class-based syntax as this is more familiar for people coming from another actor framework.

This functionality is available through the Microsoft.Azure.WebJobs.Extensions.DurableTask nuget package.

We first need to define an entity class. This class can have methods and properties just like a ‘normal’ class.

Notice 2 things:

  1. We keep our state private and only make it accessible through a method call.
  2. You can clear the entity state through calling Entity.Current.DeleteState().

Remark: It is important to follow the CQS principle when using durable entities. A method should either return data (query) or update state(command) but never do both.

There is one extra step we need to take. A Run function should be added. This function contains the boilerplate required for using the class-based syntax. It must be a static Azure Function. It executes once for each operation message that is processed by the entity. When DispatchAsync<T> is called and the entity isn't already in memory, it constructs an object of type T and populates its fields from the last persisted JSON found in storage (if any). Then it invokes the method with the matching name.

To call our entity we can use the IDurableEntityClient. An entity can either be signaled or called:

  • Calling an entity uses two-way (round-trip) communication. You send an operation message to the entity, and then wait for the response message before you continue. The response message can provide a result value or an error result, such as a JavaScript error or a .NET exception. This result or error is then observed by the caller.
  • Signaling an entity uses one-way (fire and forget) communication. You send an operation message but don't wait for a response. While the message is guaranteed to be delivered eventually, the sender doesn't know when and can't observe any result value or errors.

An example:

Thursday, December 3, 2020

ASP.NET Core WSFederation - Return 401 for API calls

By default when you configure the WSFederation middleware in ASP.NET Core, you will be redirected to the Identity Provider when an unauthenticated request arrives on the server. 

This is what you would expect when the middleware is invoked from an ASP.NET Core MVC or Razor Pages webpage but probably not what you want when it is an API. In that case a 401 would be a better response.

To achieve this you should handle the OnRedirectToIdentityProvider event and change the response to 401:

Understanding Technical Debt

To produce quality software it is really important to understand the concept of Technical Debt. Let’s see how Ward Cunningham explains it:

The key phrase in his explanation is:

“If you develop a program for a long period of time by only adding features but never reorganizing it to reflect your understanding of those features, then eventually that program simply does not contain any understanding and all efforts to work on it take longer and longer.”

The fact is that every codebase changes. Every time we change something without fully understanding the impact of this change, we are duct-taping and in fact increasing our technical debt. A general sense of confusion builds up over time that makes it harder and harder for a developer to apply a change.

You’ll end with 2 possible reactions; either the developer gives up and decides to add some extra duct tape or  demands a rewrite to get rid of this mess. The choice is yours…

So be warned, if your developers are confused, it should be a big signal to start refactoring and bring the codebase back in line with your current level of understanding.

Wednesday, December 2, 2020

Azure DevOps–dotnet pack gives wrong suggestion in ‘Path to csproj or nuspec file(s) to pack’

One of the available pipeline tasks in Azure DevOps is the dotnet core CLI task. Through this task you can execute the available command line options that dotnet offers.

One of those command line options is ‘dotnet pack’ that allows you to create nuget packages from either csproj or nuspec files.

You can specify where the task should search for these files by configuring the ‘Path to csproj or nuspec file(s) to pack’ option. However I noticed that this option didn’t work as expected. I tried to exclude some files but that didn’t work.

I found out that the suggestion next to the option was wrong. The pattern described was incorrect. The documentation mentions that you should use ‘-:’ to exclude files and folder. This is wrong, instead you should use a ‘!’:

Wrong pattern:

**/*.csproj;-:**/*.Tests.csproj

Correct pattern:

**/*.csproj;!**/*.Tests.csproj

Tuesday, December 1, 2020

ASP.NET Core–Taghelper doesn’t work in ViewComponent

Inside my ASP.NET Core application I created a custom ViewComponent that could be used to log out a user. To make my life a little bit easier I used an ASP.NET Core TagHelper  inside my component:

Unfortunately this didn’t work and instead of parsing the custom tags the TagHelpers were rendered ‘as-is’ in the HTML output:

To fix it I had to explicitly include the TagHelpers inside my ViewComponent using @addTagHelper:

@using ViewComponents.Logout

@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers