Software development is a complex task and as a developer you gain nothing from "reinventing the wheel". I'm a firm believer that you should make your life as easy as possible as a developer, by using tried and tested packages where possible; it will take so much headache out of your development experience. Below are a few of the packages that I use in most of my projects. I believe they make for an easier development experience and make my code much easier to maintain. I would recommend that you consider them for your own projects in the future. If I've missed a package that you think is super useful, please share in the comments section below. My top 4 Nuget packages are: Automapper Mediatr Swagger Fluent Validation Automapper Most software applications consist of different layers that each have their own concerns. For example, a common pattern is the . Since each layer has its own concerns and should be loosely coupled to the other layers, each layer normally has its own objects models too. 3-layered data access, logic, and presentation model For example, a user object in the logic layer may contain methods that define the behaviour of that model, whereas a user object in the presentation layer may only contain the properties necessary to be displayed in the UI. Therefore, each time data is passed up and down between layers, the objects of one layer must be converted to the objects of the next layer. For example, in an ASP.NET Core MVC application, you may typically see something like this in a controller action. : { IUserService _userService; { _userService = userService; } { domainUser = _userService.Get(id); presentationUser = PresentationUser { Id = domainUser.Id, FirstName = domainUser.FirstName, LastName = domainUser.LastName, }; JsonResult(presentationUser); } } public class UserController Controller private readonly ( ) public UserController IUserService userService Task<IActionResult> ( ) public async GetUser id int var await var new // etc return new This process is known as mapping, and I'm sure you'll agree that it can get incredibly boring and tedious to write such code, not to mention it convoluting your code with trivial procedures. This is where comes to save the day (and your sanity). It is a convention-based object-object mapper written by and it really takes a lot of the pain out of mapping objects. It really takes minimal configuration in most cases and results in much cleaner code with all of the trivial mapping code removed: Automapper Jimmy Bogard : { IUserService _userService; IMapper _mapper; { _userService = userService; _mapper = mapper; } { domainUser = _userService.Get(id); presentationUser = _mapper.Map<PresentationUser>(domainUser); JsonResult(presentationUser); } } public class UserController Controller private readonly private readonly ( ) public UserController IUserService userService, IMapper mapper Task<IActionResult> ( ) public async GetUser id int var await var return new To find out more, and . read the Automapper documentation find it in the NuGet Gallery Mediatr Mediatr is another package by and is an implementation of the . The mediator pattern is designed to reduced coupled between classes by having them interact through an intermediate mediator class. The result is easier-to-maintain code with fewer dependencies. Jimmy Bogard mediator software design pattern All interactions in Mediatr consist of a class containing the data that you want to send and a handler class for that data. There are two different types of interaction, a request and a notification. A request expects to have just one handler implementation and can expect a value to be returned from the request. : < > { UserId { ; ; } } : < , > { IUserService _userService; { _userService = userService; } { _userService.Get(request.UserId); } } : { IMediator _mediator; { _mediator = mediator; } { request = UserRequest { UserId = id }; user = _mediator.Send(request); JsonResult(user); } } public class UserRequest IRequest DomainUser public int get set public class UserRequestHandler IRequestHandler UserRequest User private readonly ( ) public UserRequestHandler IUserService userService Task<User> ( ) public async Handle UserRequest request, CancellationToken ct return await public class UserController Controller private readonly ( ) public UserController IMediator mediator Task<IActionResult> ( ) public async GetUser id int var new var await return new A notification is similar to an event. It can be broadcast to multiple handlers, each of which can do their own logic based on the notification. Notifications do not return any value. : { UserId { ; ; } } : < > { { } } : < > { { } } : { IMediator _mediator; { _mediator = mediator; } { request = UserRequest { UserId = id }; user = _mediator.Send(request); notification = UserRetrievedNotification { UserId = id }; _mediator.Publish(notification); JsonResult(user); } } public class UserRetrievedNotification INotification public int get set public class UserRetrievedNotificationHandler1 INotificationHandler UserRetrievedNotification Task ( ) public async Handle UserRetrievedNotification notification, CancellationToken ct // do some logic public class UserRetrievedNotificationHandler2 INotificationHandler UserRetrievedNotification Task ( ) public async Handle UserRetrievedNotification notification, CancellationToken ct // do some more logic public class UserController Controller private readonly ( ) public UserController IMediator mediator Task<IActionResult> ( ) public async GetUser id int var new var await var new await return new Another really cool feature of Mediatr is that you can configure a pipeline to actions to run before and after a request/notification, so you could implement exception handling or logging automatically for every request. To find out more, and . read the Mediatr documentation find it in the NuGet Gallery Swagger Swagger is a must-have if you're creating APIs using ASP.NET Core. It automatically scans all of your controllers and actions to generate an , which makes it super easy to visualise and maintain all of your API endpoints. OpenAPI document Swagger is also really useful for testing as it allows you to send requests to each of your endpoints via the browser. There's not really much more to say than that, since it requires hardly any configuration and generates everything for you. For instructions on how to install it, I would recommend . To find out more, and . this Microsoft article read the Swagger documentation find it in the NuGet Gallery Fluent Validation When receiving any input from a user, it is important to make sure that the data that they have supplied is valid and complete. You can do this to some extent on the front end using (and you definitely should do this for a better user experience), but all input should be validated again on the backend since there are a number of ways that a user could bypass the client-side validation (whether maliciously or not). client-side form validation There are a number of ways that you could set up validation on the server, but ultimately it comes down to checking each property of the input class against a set of rules. The logic for these rules will need to be defined for each input class, and, similar to the object mapping example, can be rather boring, repetitive and trivial. : { IUserService _userService; { _userService = userService; } { (user ) ArgumentNullException(); ( .IsNullOrEmpty(user.FirstName)) ArgumentException(); (user.FirstName.Length > ) ArgumentException(); result = _userService.Create(user); JsonResult(result); } } public class UserController Controller private readonly ( ) public UserController IUserService userService Task<IActionResult> ( ) public async CreateUser User user if is null throw new if string throw new if 50 throw new // etc var await return new Fluent Validation makes this whole process much more pleasant by using a to configure validation in a much less tedious way. The logic for many common types of validation is already defined, along with helpful error messages, although this can all by configured further if you wish. fluent interface pattern : < > { { RuleFor(u => u.FirstName).NotEmpty().MaximumLength( ); RuleFor(u => u.LastName).NotEmpty().MaximumLength( ); } } public class UserValidator AbstractValidator User ( ) public UserValidator 50 50 // etc To find out more, and . read the Fluent Validation documentation find it in the NuGet Gallery Conclusion These were my top 4 Nuget packages that I use in almost all of my projects. I find that they make for a much nicer development and maintenance experience, and I hope that you will find them useful too. If you know any other packages that you think should have been in this list, please let me know in the comments section below. I post mostly about full stack .NET and Vue web development. To make sure that you don't miss out on any posts, please follow this blog and . If you found this post helpful, please like it and share it. You can also . subscribe to my newsletter find me on Twitter Previously published at https://samwalpole.com/my-top-4-nuget-packages-for-aspnet-core