En la comunidad es muy común que me consulten que Add-on uso en VS Code, o como hago para mejorar mi coding o que nuget son de preferencia. Por eso decidí realizar este post con la lista de package casi fundamental para trabajar hoy con la tecnología .Net. Todas estas librerías son de código abierto y tienen gran soporte de la comunidad, así que podemos usarlas sin preocuparnos.
MediatR
Esta es una de las que tengo en top que más uso. MediatR implementa el patrón Mediator. El patrón mediator define un objeto que encapsula cómo interactúa un conjunto de objetos. Este patrón se considera un patrón de comportamiento debido a que puede alterar el comportamiento de ejecución del programa. Puedes ver la implementación desde este link.
Esta librería nos ayuda a escribir código limpio, desacoplado y extensible fácilmente. Debemos configurarlo mediante la inyección de dependencias de .Net.
Podemos usar MediatR para escribir solicitudes de tipo de consulta de comando simple usando la interfaz IRequest . IRequest maneja los mensajes enviados a un solo handler. Algunos ejemplos de tipos de IRequests en una aplicación web estándar pueden ser: GetUserQuery o UpdateCartCommand. Veamos el siguiente ejemplo, se utiliza una clase anidada interna para mantener el modelo de consulta y el controlador de consultas juntos en una clase.
//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));
Mediatr admite mensajes de notificación que pueden tener varios controladores a través de la interface INotification. Las notificaciones funcionan de manera similar a las solicitudes, pero no retornan valores. Son excelentes para exponer una “Extension point” en las aplicaciones que construiremos más tarde.
Serilog
Serilog se ha vuelto el más popular entre los componentes para logging y posee una gran comunidad que la respalda. Serilog proporciona un registro estructurado que puede orientar a cualquier tipo de repositorio. Estos registros estructurados se capturan en formato del tipo json. Esto no da mucho más contexto sobre lo que está sucediendo en nuestras aplicaciones y, con las herramientas adecuadas, podemos consultar y analizar con más detalle los registros.
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}
Como comenté anteriormente, Serilog, tiene una comunidad muy grande. Han escrito agentes recolectores, y que escriben registros a un proveedor para casi todos los servicios podríamos imaginar como Cloud Watch o AppInsight. En la página de Github podemos echar un vistazo a todos los disponibles links. Otros 2 muy útiles son: Seq, una herramienta para visualizar los registros, Sentry, un servicio de informes.
Hangfire
Este componente nos brinda una manera fácil de realizar tareas programadas o disparar trabajos en segundo plano para aplicaciones .NET Core y Framework. Lo mejor, es lo fácil que es comenzar a trabajar. Estos pueden ejecutarse en el proceso principal de nuestra aplicación sin la necesidad de un servicio dedicado para esto.
//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());
Hangfire viene con un excelente tablero integrado, con soporte de inyección de dependencia y opciones de almacenamiento para Microsoft SQL server, postgreSQL, Redis y muchos más.
LazyCache
Este es un contenedor sencillo, seguro para subprocesos y fácil de desarrollar para almacenar en caché en memoria en .Net. Si bien existen otros componentes o servicios para realizar esto, lo recomiendo por su simpleza de uso.
LazyCache utiliza un patrón que se llama “GetOrADD” para almacenar en el caché lo que necesitemos, solicitamos un elemento del cache y al mismo tenemos disponible agregar elementos al caché si lo deseamos.
var model = await cache.GetOrAddAsync("HomePageData"
async () =>
{
return homePageService.GetData(); //function to get cachable data
}
, new TimeSpan(12, 0, 0) //12 hour cache expiry
);
Una característica interesante es que LazyCache es fácil de ampliar, si necesitamos pasar de un simple caché de memoria a algo distribuido, el cambio debería ser bastante sencillo y sin complicaciones.
Dapper
A veces, el acceso a datos SQL con Entity Framework es excesivo o simplemente demasiado lento, sobre todo cuando estamos haciendo consultas solamente. Cuando deseamos ejecutar SQL sin formato, pero aun así queremos obtener un buen mapeo de objetos, Dapper es nuestro componente a usar.
Dapper toma su conexión de base de datos existente y agrega métodos de extensión para ejecutar SQL sin procesar y asignarlo de nuevo a las clases de C #.
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
);
MiniProfiler
MiniProfiler es un generador de perfiles de rendimiento simple para aplicaciones web .NET Core y framework (también Ruby, Go y Node). Lo adjuntamos automáticamente a las partes clave de nuestra aplicación, principalmente al acceso a la base de datos. MiniProfiler generará un pequeño resultado de sincronización increíble directamente en nuestra aplicación. Especial para ejecutar durante el desarrollo para detectar consultas LINQ no autorizadas.
MiniProfiler tiene una excelente documentación para configurarlo con muchísimas opciones. Recordemos que, por razones de seguridad, solo se ha habilitado durante tiempo desarrollo.
LinqKit
Para los fanáticos de LinQ, LINQKit es un conjunto de extensiones para consultar Entity Framework con Linq. LINQKit le permite crear consultas y condiciones de linq como predicados. Los usos para simplificar consultas con muchos parámetros (muchos filtros) usando PredicateBuilder.
//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);
Conclusiones
Todas está librerías deben ser usadas para situaciones particulares, tampoco debemos usarlas porque sí. Espero que les agrade la lista de paquetes para nuestros proyectos .Net. en la parte 2 veremos algunos más.