0% found this document useful (0 votes)
8 views

Documento 29-1

El documento describe la implementación del patrón Repository en un proyecto de programación para reducir la redundancia de código en varias clases de repositorio. Se ha utilizado herencia y genéricos para crear un repositorio genérico que maneja operaciones comunes, permitiendo la reutilización de la lógica. Además, se solicita la opinión del profesor sobre los cambios realizados para confirmar su validez y posibles mejoras.

Uploaded by

Canal TORO
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

Documento 29-1

El documento describe la implementación del patrón Repository en un proyecto de programación para reducir la redundancia de código en varias clases de repositorio. Se ha utilizado herencia y genéricos para crear un repositorio genérico que maneja operaciones comunes, permitiendo la reutilización de la lógica. Además, se solicita la opinión del profesor sobre los cambios realizados para confirmar su validez y posibles mejoras.

Uploaded by

Canal TORO
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

Buenas tardes Rafa,

He notado que en el código actual, varias funciones se repiten en


las clases CategoryRepository, EditorialRepository, HouseRepository,
LibroRepository y SovietTankRepository. Esto genera código
redundante, lo que no es una buena práctica en programación.

Para mejorar la estructura y hacer el código más flexible, he


aplicado el patrón Repository utilizando herencia y genéricos. Esto
nos permite reutilizar la lógica común y adaptarla a diferentes
entidades según sea necesario.

Me gustaría consultar con usted, profesor, sobre los cambios que


realicé para confirmar si estoy en el camino correcto o si hay
aspectos que podría mejorar. ¿Qué opina?
using System.Collections.Generic;

using System.Threading.Tasks;

namespace RestAPI.Repository

public interface IRepository<T> where T : class

Task<ICollection<T>> GetAllAsync();

Task<T> GetAsync(int id);

Task<bool> ExistsAsync(int id);

Task<bool> CreateAsync(T entity);

Task<bool> UpdateAsync(T entity);

Task<bool> DeleteAsync(int id);

Task<bool> Save();

void ClearCache();

********************************************************************
*******

using RestAPI.Models.Entity;

namespace RestAPI.Repository.IRepository

public interface ILibroRepository : IRepository<LibroEntity> { }

********************************************************************
*******

using RestAPI.Models.Entity;
namespace RestAPI.Repository.IRepository

public interface IEditorialRepository:IRepository<EditorialEntity>

********************************************************************
*******

using RestAPI.Models.Entity;

using RestAPI.Repository;

namespace RestAPI.Repository.IRepository

public interface IHouseRepository : IRepository<HouseEntity>

********************************************************************
*******

using RestAPI.Models.Entity;

using RestAPI.Repository;

namespace RestAPI.Repository.IRepository

public interface ICategoryRepository : IRepository<Category>

{
}

********************************************************************
*******

using RestAPI.Models.Entity;

namespace RestAPI.Repository.IRepository

public interface ISovietTanksRepository :


IRepository<SovietTankEntity>

********************************************************************
*******

using RestAPI.Models.DTOs.UserDto;

using RestAPI.Models.Entity;

namespace RestAPI.Repository.IRepository

public interface IUserRepository

ICollection<AppUser> GetUsers();

AppUser GetUser(string id);

bool IsUniqueUser(string userName);

Task<UserLoginResponseDto> Login(UserLoginDto userLoginDto);

Task<UserLoginResponseDto> Register(UserRegistrationDto
userRegistrationDto);

}
********************************************************************
*******

using Microsoft.EntityFrameworkCore;

using Microsoft.Extensions.Caching.Memory;

using RestAPI.Data; using System;

using System.Collections.Generic;

using System.Linq;

using System.Threading.Tasks;

namespace RestAPI.Repository

{ public class GenericRepository : IRepository where T : class

protected readonly ApplicationDbContext _context;

protected readonly IMemoryCache _cache;

private readonly DbSet _dbSet;

private readonly string _cacheKey;

private readonly int _cacheExpirationTime = 3600;

public GenericRepository(ApplicationDbContext context,


IMemoryCache cache)
{
_context = context;
_cache = cache;
_dbSet = _context.Set<T>();
_cacheKey = $"{typeof(T).Name}CacheKey";
}

public async Task<bool> Save()


{
var result = await _context.SaveChangesAsync() >= 0;
if (result) ClearCache();
return result;
}
public void ClearCache()
{
_cache.Remove(_cacheKey);
}

public async Task<ICollection<T>> GetAllAsync()


{
if (_cache.TryGetValue(_cacheKey, out ICollection<T>
cachedData))
return cachedData;

var dataFromDb = await _dbSet.ToListAsync();


var cacheOptions = new MemoryCacheEntryOptions()

.SetAbsoluteExpiration(TimeSpan.FromSeconds(_cacheExpirationTime));

_cache.Set(_cacheKey, dataFromDb, cacheOptions);


return dataFromDb;
}

public async Task<T> GetAsync(int id)


{
if (_cache.TryGetValue(_cacheKey, out ICollection<T>
cachedData))
{
var entity = cachedData.FirstOrDefault(c =>
EF.Property<int>(c, "Id") == id);
if (entity != null) return entity;
}
return await _dbSet.FindAsync(id);
}

public async Task<bool> ExistsAsync(int id)


{
return await _dbSet.AnyAsync(c => EF.Property<int>(c, "Id")
== id);
}

public async Task<bool> CreateAsync(T entity)


{
await _dbSet.AddAsync(entity);
return await Save();
}

public async Task<bool> UpdateAsync(T entity)


{
_dbSet.Update(entity);
return await Save();
}

public async Task<bool> DeleteAsync(int id)


{
var entity = await GetAsync(id);
if (entity == null) return false;

_dbSet.Remove(entity);
return await Save();
}
}

********************************************************************
*********

using RestAPI.Data;

using RestAPI.Models.Entity;

using RestAPI.Repository.IRepository;

using Microsoft.Extensions.Caching.Memory;

namespace RestAPI.Repository

public class LibroRepository : GenericRepository<LibroEntity>,


ILibroRepository

public LibroRepository(ApplicationDbContext context,


IMemoryCache cache)

: base(context, cache) { }

}
}

********************************************************************
*********

using RestAPI.Data;

using RestAPI.Models.Entity;

using RestAPI.Repository.IRepository;

using Microsoft.Extensions.Caching.Memory;

namespace RestAPI.Repository

public class CategoryRepository: GenericRepository<


CategoryEntity>, ICategoryRepository

public CategoryRepository (ApplicationDbContext context,


IMemoryCache cache)

: base(context, cache) { }

********************************************************************
*********

namespace RestAPI.Repository

public class EditorialRepository: GenericRepository<


EditorialEntity>, I EditorialRepository

public EditorialRepository (ApplicationDbContext context,


IMemoryCache cache)

: base(context, cache) { }

}
}

********************************************************************
*********

using RestAPI.Data;

using RestAPI.Models.Entity;

using RestAPI.Repository.IRepository;

using Microsoft.Extensions.Caching.Memory;

namespace RestAPI.Repository

public class HouseRepository: GenericRepository< HouseEntity>,


IHouseRepository

public HouseRepository (ApplicationDbContext context,


IMemoryCache cache)

: base(context, cache) { }

********************************************************************
*********

using RestAPI.Data;

using RestAPI.Models.Entity;

using RestAPI.Repository.IRepository;

using Microsoft.Extensions.Caching.Memory;

namespace RestAPI.Repository

public class SovietTankRepository: GenericRepository<


SovietTankEntity>, ISovietTankRepository

{
public SovietTankRepository (ApplicationDbContext context,
IMemoryCache cache)

: base(context, cache) { }

********************************************************************
*********

using RestAPI.Data;

using RestAPI.Models.Entity;

using RestAPI.Repository.IRepository;

using Microsoft.Extensions.Caching.Memory;

namespace RestAPI.Repository

public class SovietTankRepository: GenericRepository<


SovietTankEntity>, ISovietTankRepository

public SovietTankRepository (ApplicationDbContext context,


IMemoryCache cache)

: base(context, cache) { }

********************************************************************
*********

using RestAPI.Data;

using RestAPI.Models.DTOs.UserDto;

using RestAPI.Repository.IRepository;

using AutoMapper;

using Microsoft.AspNetCore.Identity;
using Microsoft.IdentityModel.Tokens;

using System.IdentityModel.Tokens.Jwt;

using System.Security.Claims;

using System.Text;

using System.Security.Cryptography;

using RestAPI.Models.Entity;

namespace RestAPI.Repository

public class UserRepository : IUserRepository

private readonly ApplicationDbContext _context;

private readonly string secretKey;

private readonly UserManager<AppUser> _userManager;

private readonly RoleManager<IdentityRole> _roleManager;

private readonly IMapper _mapper;

private readonly int TokenExpirationDays = 7;

public UserRepository(ApplicationDbContext context,


IConfiguration config,

UserManager<AppUser> userManager,
RoleManager<IdentityRole> roleManager, IMapper mapper)

_context = context;

secretKey =
config.GetValue<string>("ApiSettings:SecretKey");

_userManager = userManager;

_roleManager = roleManager;

_mapper = mapper;

}
public AppUser GetUser(string id)

return _context.AppUsers.FirstOrDefault(user => user.Id


== id);

public ICollection<AppUser> GetUsers()

return _context.AppUsers.OrderBy(user =>


user.UserName).ToList();

public bool IsUniqueUser(string userName)

return !_context.AppUsers.Any(user => user.UserName ==


userName);

public async Task<UserLoginResponseDto> Login(UserLoginDto


userLoginDto)

var user = _context.AppUsers.FirstOrDefault(u =>


u.UserName.ToLower() == userLoginDto.UserName.ToLower());

bool isValid = await


_userManager.CheckPasswordAsync(user, userLoginDto.Password);

//user doesn't exist ?

if (user == null || !isValid)

{
return new UserLoginResponseDto { Token = "", User =
null };

//User does exist

var roles = await _userManager.GetRolesAsync(user);

var tokenHandler = new JwtSecurityTokenHandler();

if (secretKey.Length < 32)

throw new ArgumentException("The secret key must be


at least 32 characters long.");

var key = Encoding.ASCII.GetBytes(secretKey);

var tokenDescriptor = new SecurityTokenDescriptor

Subject = new ClaimsIdentity(new Claim[]

new Claim(ClaimTypes.Name,
user.UserName.ToString()),

new Claim(ClaimTypes.Role,
roles.FirstOrDefault())

}),

Expires =
DateTime.UtcNow.AddMinutes(TokenExpirationDays),

SigningCredentials = new(new
SymmetricSecurityKey(key), SecurityAlgorithms.HmacSha256Signature)

};
var jwtToken =
tokenHandler.CreateToken(tokenDescriptor);

UserLoginResponseDto userLoginResponseDto = new


UserLoginResponseDto

Token = tokenHandler.WriteToken(jwtToken),

User = user

};

return userLoginResponseDto;

public async Task<UserLoginResponseDto?>


Register(UserRegistrationDto userRegistrationDto)

AppUser user = new AppUser()

UserName = userRegistrationDto.UserName,

Name = userRegistrationDto.Name,

Email = userRegistrationDto.UserName,

NormalizedEmail =
userRegistrationDto.UserName.ToUpper(),

};

var result = await _userManager.CreateAsync(user,


userRegistrationDto.Password);

if (!result.Succeeded)

return null;
}

if (!await _roleManager.RoleExistsAsync("admin"))

//this will run only for first time the roles are
created

await _roleManager.CreateAsync(new
IdentityRole("admin"));

await _roleManager.CreateAsync(new
IdentityRole("register"));

await _userManager.AddToRoleAsync(user, "admin");

AppUser? newUser = _context.AppUsers.FirstOrDefault(u =>


u.UserName == userRegistrationDto.UserName);

return new UserLoginResponseDto

User = newUser

};

You might also like