Records make my code shorter. For example, instead of
public class OrderService
{
private readonly EcommerceContext _context;
public OrderService(EcommerceContext context)
{
_context = context;
}
}
I just have
public record OrderService(EcommerceContext Context)
So, my question is, is it ok to inject a record in the DI container, or does it have any disadvantage?
CodePudding user response:
A record is just a class with a auto-generated constructor; The DI Container doesn't distinguish between the two of them.
Personally, I find record types a great way to remove the infrastructural code/cruft needed to practice DI and loose coupling. Private fields, constructors, and private field assignments are just boilerplate code required to allow our code to be loosely coupled. Records allow reducing this code to the bare minimum, which is great.
The only downside that record types have is that, with the current version of C#, there's no way to guard incoming dependencies from being null
. For me this isn't big of a deal in most cases, in which case I like to use record types. If null checks are mandatory (for instance because you are writing a reusable library, e.g. something you ship through NuGet), you need to fall back to old-school classes with manually implemented constructors.
When writing our book on DI, Mark Seemann and I actually discussed the use of record types as primary demonstration of constructor injection in our book. We, however, decided not to use record types in our book, mainly for three reasons:
- At the time of publishing, C# 9, which included record types, was not yet available
- The loss of the ability to do pre-condition checking was a deal breaker for the examples of the book, because we didn't want to assume a DI Container was used for composing instances; there's also a practice called Pure DI which we describe extensively in the book. With Pure DI there is no tooling that guarantees not injecting
null
values into constructors. - We wanted the book to be readable for developers working in other OOP languages as well. Even though record types will be very common within the C# community within a few years, that might not be the case for many other OOP languages.
Perhaps we'll change our mind in a (hypothetical) third edition of the book. This might especially happen when a future version of C# allows record type constructors to automatically check (and prevent) null arguments.