14 .NET packages I always recommend
Tags: dotnet, opensource, csharp, nuget
Published: 2021-03-22 21:07:19

---
title: 14 .NET packages I always recommend
published: true
date: 2021-03-20 02:26:20 UTC
tags: dotnet,opensource,csharp,nuget
canonical_url: https://lukelowrey.com/recommended-dotnet-libraries/
---

 ![14 .NET packages I always recommend](https://lukelowrey.com/content/images/2021/03/nuget-cover-min.png)

This post lists open source libraries available on [Nuget.org](http://nuget.org/) that I regularly use and recommend. These packages will save you time and make your applications better. They have good documentation and a great developer experience.

### MediatR

[MediatR](https://github.com/jbogard/MediatR) is a simple in-process implementation of the [mediator pattern](https://en.wikipedia.org/wiki/Mediator_pattern). It helps developer write clean, decoupled and extendable code. Mediator is configured using dependency injection with out of the box support for .NET Core, Autofac and others. The [documentation on Github](https://github.com/jbogard/MediatR/wiki) is the best place to get started.

I like to use MediatR to write simple command query type requests using the _IRequest_ interface. _IRequest_ handle messages sent to a single handler. Examples of types of _IRequests_ in a standard web application might be "_GetUserQuery_" or "_UpdateCartCommand_". The example below uses an internal nested class to keep the query model and query handler together in one class.

```cs
//a simple "query" type request
public class GetUserQuery : IRequest<User>
{
    public int UserID { get; set; }

    internal class GetUserQueryHandler : IRequestHandler<UserGetQuery, UserDto>
    {
        private readonly UserService _userService;

        public UserGetQueryHandler(UserService userService)
        {
            _userService = userService;
        }

        public async Task<UserDto> Handle(GetUserQuery request, CancellationToken cancellationToken)
        {
            //normlly something more extensive here...
            return await _userService.GetUser(request.UserID);
        }
    }
}

//calling code
var user = await mediator.Send(new GetUserQuery(1));
```
<figcaption>A simple "query" type mediatr request</figcaption>

Mediatr also supports notification messages which can have multiple handlers through INotification. Notifications work in a similar way to requests but don't return values. They are great for exposing a "extension point" in your application that you may need to build on later.

> As a side note: everything [Jimmy Bogard](https://jimmybogard.com/) writes code or otherwise is great.

### Serilog

[Serilog](https://serilog.net/) provides _structured_ logging which can target output to just about anywhere. Structured logs capture your log statements and objects as json. They give much more context into what is happening in your application and with the right tools they can be queried and analysed in more detail than standard text logs.

```cs
var position = new { Latitude = 25, Longitude = 134 };
var elapsedMs = 34;

log.Information("Processed {@Position} in {Elapsed:000} ms.", position, elapsedMs);

//log output
//{"Position": {"Latitude": 25, "Longitude": 134}, "Elapsed": 34}
```
<figcaption>Example from Serilog website</figcaption>

One of the best things about Serilog is the community has written sinks - which write logs to an provider for just about every service you can think of. The [provided sinks](https://github.com/serilog/serilog/wiki/Provided-Sinks) Github page has a full list. A couple I recommend checking out:

- [Seq](https://datalust.co/seq) - self hosted structured log viewer
- [Sentry](https://sentry.io/)- exception reporting service that plugs in automatically to _error_ log events

### Hangfire

[Hangfire](https://www.hangfire.io/) is an easy way to perform scheduled or fire-and forget background jobs for .NET Core and Framework applications. I love how easy it is to get up an running as the jobs can run in your app's main process without requiring a dedicated service.

```cs
//Fire and forget
BackgroundJob.Enqueue(() => {
	Console.WriteLine("This will run once, in the background");
});

//Recurring job
RecurringJob.AddOrUpdate(
    () => {
    	Console.WriteLine("This will run daily");
    },
    Cron.Daily
);

//Calling a dependency injection job
BackgroundJob.Enqueue<MyService>(myService => myService.Execute());
```
<figcaption>Example Hangfire jobs</figcaption>

Hangfire has a great built in dashboard, dependency injection support and storage options for SQL server, PostgreSQL, Redis and more.

![14 .NET packages I always recommend](https://lukelowrey.com/content/images/2021/03/image.png)<figcaption>Hangfire dashboard</figcaption>

### FluentEmail

[FluentEmail](https://github.com/lukencode/FluentEmail) (written by me) helps you implement complete email sending functionality in your app in less than 10 minutes. It features built in providers for the most popular email senders including SendGrid and Mailgun along with Razor templates out of the box. I recently wrote a [full guide to .NET email using FluentEmail](https://lukelowrey.com/dotnet-email-guide-2021/) that will get you started.

```cs
var email = await Email
    .From("bill.gates@microsoft.com")
    .To("luke.lowrey@example.com", "Luke")
    .Subject("Hi Luke!")
    .Body("Fluent email looks great!")
    .SendAsync();
```
<figcaption>Send an email with FluentEmail</figcaption>
### LazyCache

[LazyCache](https://github.com/alastairtree/LazyCache) is an easy to use, thread safe and developer friendly wrapper for in-memory caching in .NET Core. I've [written a bit about LazyCache](https://lukelowrey.com/caching-in-aspnet-core-with-lazycache/) in the past and I still reach for it every time I need a cache provider.

LazyCache uses a "GetOrAdd" pattern for caching where you request an item from the cache and at the same time provide the function to add that item to the cache if it is missing.

```cs
var model = await cache.GetOrAddAsync("HomePageData", 
   async () =>
   {
       return homePageService.GetData(); //function to get cachable data
   }
   , new TimeSpan(12, 0, 0) //12 hour cache expiry
); 
```
<figcaption>Example cache GetOrAdd call</figcaption>

LazyCache is easy to extend so if you need to move beyond a simple in memory cache to something distributed the step up should be pretty seamless.

### Dapper

Sometimes SQL data access with Entity Framework is overkill or just _too slow_. When you want to run raw SQL but still get some nice object mapping [Dapper](https://github.com/StackExchange/Dapper) is the way to go.

> Dapper is a [NuGet library](https://www.nuget.org/packages/Dapper) that you can add in to your project that will extend your `IDbConnection` interface.

Dapper takes your existing database connection and adds extension methods to run raw SQL and map it back to C# classes.

```cs
public class Dog
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Age { get; set; }
}

var dogs = connection.Query<Dog>(
    "select * from Dogs where Age > @Id", //sql query, @ parameters
    new { Age = 5 } //anonymous object to map parameters
);

```
<figcaption>Example dapper query</figcaption>
### MiniProfiler

[MiniProfiler](https://miniprofiler.com/) is a simple performance profiler for .NET Core and framework (also Ruby, Go and Node) web applications. It attaches automatically to the key parts of your application - mainly database access. MiniProfiler will then render an awesome little timing result directly on your app. It is great for running during development to pick up rogue LINQ queries.

![14 .NET packages I always recommend](https://lukelowrey.com/content/images/2021/02/image-6.png)<figcaption>MiniProfiler results</figcaption>

MiniProfiler has [great setup documentation](https://miniprofiler.com/dotnet/AspDotNet) with a heap of options. For security reasons, I normally only have it enabled during development.

### LinqKit

LINQKit is a set of extensions for querying Entity Framework with Linq. LINQKit allows you to build linq queries and conditions as predicates.

My most common use for LINQKit is simplifying queries with lots of criteria (think grids with filters) using the PredicateBuilder.

```cs
//base linq query
var users = from u in context.Users
            select u;

//add conditions as required
var predicate = PredicateBuilder.New<User>(true);

if (!string.IsNullOrWhiteSpace(filters.Name))
    predicate.And(u => u.Name.Contains(filters.Name));

if (!string.IsNullOrWhiteSpace(filters.Email))
    predicate.And(u => u.Email.Contains(filters.Email));

//apply conditions to query
var filteredUsers = users.AsExpandable().Where(predicate);
```
<figcaption>Example LINQKit predicate usage to add optional query conditions</figcaption>
### FluentMigrator or DbUp

If you are looking for an alternative to running EntityFramework code first migrations both FluentMigrator and DbUp will do the job.

[DbUp](https://dbup.github.io/) works best if you like raw SQL and simple scripts. You simply create a console application and add SQL files as embedded resources. Some simple code in Program.cs will run your migration scripts in order - easy to integrate into a devops pipeline.

![14 .NET packages I always recommend](https://lukelowrey.com/content/images/2021/02/image-7.png)<figcaption>Embedded scripts</figcaption>

```cs
static int Main(string[] args)
{
    var connectionString = args.FirstOrDefault(); //or some configuration

    var upgrader =
        DeployChanges.To
            .SqlDatabase(connectionString)
            .WithScriptsEmbeddedInAssembly(Assembly.GetExecutingAssembly())
            .LogToConsole()
            .Build();

    var result = upgrader.PerformUpgrade();
    //omitted error handling...
    return 0;
}
```
<figcaption>Program.cs</figcaption>

[FluentMigrator](https://fluentmigrator.github.io/) takes a similar concept with a more code-based approach. Instead of adding raw scripts you create small classes for each migration. This approach gives you more flexibility in building migrations (and saves you remembering the create foreign key sql syntax) and allows for more complete up/down migration scenarios.

```cs
using FluentMigrator;

namespace Migrations
{
    [Migration(20180430121800)]
    public class AddLogTable : Migration
    {
        public override void Up()
        {
            Create.Table("Log")
                .WithColumn("Id").AsInt64().PrimaryKey().Identity()
                .WithColumn("Text").AsString();
        }

        public override void Down()
        {
            Delete.Table("Log");
        }
    }
}

```
<figcaption>Example migration creating a Log table</figcaption>
### CsvHelper

[CsvHelper](https://joshclose.github.io/CsvHelper/) is my go to package for reading and writing csv files.  The library is flexible enough that you can creating custom mapping classes and rules for your C# classes or use the low level row and column methods directly.

```cs
//import csv to a class
using (var reader = new StreamReader("importfile.csv"))
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
   csv.Context.RegisterClassMap<YourClassMap>(); //optionally use a mapping class
   var records = csv.GetRecords<YourClass>();
}

//use a mapping class
public class YourClass
{
    public int Id { get; set; }
    public string Name { get set; }
}

public sealed class YourClassMap : ClassMap<YourClass>
{
    public FooMap()
    {
        Map(m => m.Id).Name("Identifier"); //overrider column names and more
        Map(m => m.Name).Name("TheName");
    }
}

//or access columns directly
using (var csv = new CsvReader(reader, CultureInfo.InvariantCulture))
{
    csv.ReadHeader();
    while (csv.Read())
    {
        var id csv.GetField<int>("Id"),
        var name = csv.GetField("Name");
    }
}
```
<figcaption>Import csv file examples</figcaption>

There are similar options for exporting csv files either with direct column writes or using classes and mapping.

```cs
using (var writer = new StreamWriter("path\\to\\file.csv"))
using (var csv = new CsvWriter(writer, CultureInfo.InvariantCulture))
{
   csv.WriteRecords(records);
}
```
<figcaption>Simple export csv example</figcaption>
### Hashids

[Hashids for .NET](https://hashids.org/net/) generates short, unique string identifiers from integers - similar to YouTube video ids. It is great for turning one or more integers into a single short, non sequencial hashes to use in urls and sharing. Just don't use it in place of security.

```cs
var hashids = new Hashids("example salt");

//creates "R9tGSE" hash
var id = hashids.Encode(1, 2, 3);

//decodes "R9tGSE" back into int[] {1, 2, 3}
var numbers = hashids.Decode(id);
```

### Humanizer

[Humanizer](https://github.com/Humanizr/Humanizer) is for turning dates, numbers, enums and more in human friendly readable strings. It supports lots of data types and can be used with multiple languages.

```cs
//These are some methods I use all the time, check out the documentation for the full list

//dates
DateTime.UtcNow.AddHours(-25).Humanize() => "yesterday"
DateTime.UtcNow.AddHours(4).Humanize() => "4 hours from now"

//timespan
TimeSpan.FromDays(16).Humanize() => "2 weeks"

//Pluralize and singularize
"Dog".Pluralize() => "Dogs"
"Dogs".Singularize() => "Dog"

//truncate
"Long text to truncate".Truncate(10) => "Long text…"
```
<figcaption>Common Humanizer methods</figcaption>
### Bogus

[Bogus](https://github.com/bchavez/Bogus) is a "fake" data generator for .NET. I shudder at the thought of generating "demo" data and "test" data but Bogus takes a bit part of that pain away.

Bogus allow you to map you C# classes to fake data to quickly generate lots of data. It is also possible to access the underlying methods directly and generate a phone number, email address etc on demand.

```cs
//map a class
var userIds = 0;
var testUsers = new Faker<User>()
	.RuleFor(b => b.Id, (f, u) => userIds++)
	.RuleFor(u => u.FirstName, (f, u) => f.Name.FirstName(u.Gender))
	.RuleFor(u => u.LastName, (f, u) => f.Name.LastName(u.Gender))
	.RuleFor(u => u.Avatar, f => f.Internet.Avatar())
	.RuleFor(u => u.UserName, (f, u) => f.Internet.UserName(u.FirstName, u.LastName))
	.RuleFor(u => u.Email, (f, u) => f.Internet.Email(u.FirstName, u.LastName));

//generate users
var user = testUsers.Generate();

//use methods directly
var faker = new Faker("en");
faker.Internet.DomainName(); //eg "sylvester.com"
faker.Company.Bs().Dump(); // eg "enable leading-edge architectures"
```
<figcaption>Simple Bogus data generation examples</figcaption>

### Honourable mentions

I also love these libraries but this post was taking me forever to finish.

- [FluentValidation](https://fluentvalidation.net/)
- [AutoMapper](https://docs.automapper.org/en/stable/)
- [Autofac](https://autofac.org/)- if you are stuck on .NET framework this if your best dependency injection option

* * *

_If you enjoyed the post, please share the thread on Twitter and let me know if I missed out your favourite libraries._

{% twitter 1374102332225490947 %}