Sunteți pe pagina 1din 7

Crear un proyecto de “Blank Solution”

Proyecto de Class Library .NET Standar (Shop.Core)

 Proyecto de Class Library .NET Core (Shop.Infraestructure)


 Proyecto de API Rest .NET Core (Shop.Api)

En Shop.Core creamos las carpetas Entities y Interfaces

En la carpeta Entities creamos la clase BaseEntity

En la carpeta Interfaces/Repositories creamos la clase IBaseRepository y ponemos el siguiente código


public interface IBaseRepository<T> where T : BaseEntity
{
T FindById(int id);

IQueryable<T> FindAll();

void Add(T entity);

void Update(T entity);

void Delete(T entity);


}

En Shop.Infraestructure

Creamos la carpeta Data y dentro de esta creamos las carpetas Contexts y Repositories

Instalamos las siguientes librerias

Microsoft.EntityFrameworkCore.SqlServer

Microsoft.EntityFrameworkCore.Tools

En el package manager console ingresamos el siguiente comando

Scaffold-DbContext "Server=localhost;Database=Shop;User
ID=sa;Password=1234;Trusted_Connection=True;" Microsoft.EntityFrameworkCore.SqlServer -OutputDir
Data\Contexts

Se crean en la carpeta Data/Contexts las clases ShopContext y Productos

La clase Productos pasar a la carpeta Entities en el proyecto Shop.Core y borrar esa clase de la carpeta
Data/Contexts

En Shop.Core

En la carpeta Interfaces/Repositories creamos la interface IProductRepository


public interface IProductRepository : IBaseRepository<Productos>
{
}

En la carpeta Interfaces/Services creamos la interface IProductService


public interface IProductService
{
Task<IEnumerable<Productos>> FindAllAsync();

Productos FindById(int id);

Task<BaseCRUDResponse> SaveAsync(Productos product);

Task<BaseCRUDResponse> UpdateAsync(int id, Productos product);

Task<BaseCRUDResponse> DeleteAsync(int id);


}

Se crea la carpeta DTO y dentro de esta las carpetas Requests y Responses

En la carpeta Responses creamos la clase BaseCRUDResponse

public abstract class BaseCRUDResponse


{
public string title { get; protected set; }
public int status { get; protected set; }

public BaseCRUDResponse(string title, int status)


{
this.title = title;
this.status = status;
}

public virtual bool IsSuccess()


{
return false;
}
}

Creamos la clase ErrorCRUDResponse

public class ErrorCRUDResponse : BaseCRUDResponse


{
public ErrorCRUDResponse(string title, int status) : base(title, status)
{
}
}

Creamos la clase SuccessCRUDResponse

public class SuccessCRUDResponse : BaseCRUDResponse


{
public dynamic Data { get; protected set; }

public SuccessCRUDResponse(string title, dynamic data) : base(title, 200)


{
this.Data = data;
}

public override bool IsSuccess()


{
return true;
}
}
En la carpeta Intefaces creamos la clase IUnitOfWork
public interface IUnitOfWork
{
Task CompleteAsync();
}

En el proyecto Shop.Infraestructure

En la carpeta Data/Repositories creamos la clase BaseRepository


public abstract class BaseRepository<T> : IBaseRepository<T> where T : BaseEntity
{
protected readonly ShopContext _context;

public BaseRepository(ShopContext context)


{
_context = context;
}

public void Add(T entity)


{
this._context.Set<T>().Add(entity);
}

public void Delete(T entity)


{
this._context.Set<T>().Remove(entity);
}

public T FindById(int id)


{
return this._context.Set<T>().Find(id);
}

public IQueryable<T> FindAll()


{
return this._context.Set<T>();
}

public void Update(T entity)


{
this._context.Set<T>().Update(entity);
}
}

En la carpeta Data/Repositories creamos la clase ProductRepository


public class ProductRepository : BaseRepository<Productos>, IProductRepository
{
public ProductRepository(ShopContext context) : base(context)
{

}
}

En la carpeta Data/Repositories creamos la clase UnitOfWork


public class UnitOfWork : IUnitOfWork
{
private readonly ShopContext _context;

public UnitOfWork(ShopContext context)


{
_context = context;
}

public async Task CompleteAsync()


{
await _context.SaveChangesAsync();
}
}

En el Proyecto Shop.Infraestructure creamos la carpeta Services

En Services creamos la clase ProductService

public class ProductService : IProductService


{
private readonly IProductRepository _productRepository;
private readonly IUnitOfWork _unitOfWork;

public ProductService(IProductRepository productRepository, IUnitOfWork


unitOfWork)
{
_productRepository = productRepository;
_unitOfWork = unitOfWork;
}

public async Task<IEnumerable<Productos>> FindAllAsync()


{
return await this._productRepository.FindAll().ToListAsync();
}

public Productos FindById(int id)


{
return this._productRepository.FindById(id);
}

public async Task<BaseCRUDResponse> SaveAsync(Productos product)


{
try
{
this._productRepository.Add(product);
await _unitOfWork.CompleteAsync();

return new SuccessCRUDResponse("Producto creado", product);


}
catch (Exception e)
{
return new ErrorCRUDResponse(e.Message, 400);
}
}

public async Task<BaseCRUDResponse> UpdateAsync(int id, Productos product)


{
var result = this._productRepository.FindById(id);
if (result == null)
{
return new ErrorCRUDResponse($"No existe producto con id {id}", 404);
}

result.Marca = product.Marca;
result.Nombre = product.Nombre;
result.PrecioUnitario = product.PrecioUnitario;
result.Stock = product.Stock;
result.Tipo = product.Tipo;
result.Unidades = product.Unidades;

this._productRepository.Update(result);
await _unitOfWork.CompleteAsync();

return new SuccessCRUDResponse("Producto actualizado", result);


}

public async Task<BaseCRUDResponse> DeleteAsync(int id)


{
var result = this._productRepository.FindById(id);
if (result == null)
{
return new ErrorCRUDResponse($"No existe producto con id {id}", 404);
}

this._productRepository.Delete(result);
await _unitOfWork.CompleteAsync();

return new SuccessCRUDResponse("Producto eliminado", result);


}
}

En el Proyecto Shop.Api

Configuramos la cadena de conexion en appsettings.json

{
"ConnectionStrings": {
"DefaultConnection": "Server=DESKTOP-LF8HS6S\\SQLEXPRESS;Database=Shop;User
ID=sa;Password=1234;Trusted_Connection=True;"
},

Vamos a la clase StartUp, en el método ConfigureServices agregamos lo siguiente

Al inicio:

var connectionString = Configuration.GetConnectionString("DefaultConnection");


services.AddDbContext<ShopContext>(options =>
options.UseSqlServer(connectionString));

Al final:

//Repositorios
services.AddScoped<IProductRepository, ProductRepository>();

//Servicios
services.AddScoped<IProductService, ProductService>();
services.AddScoped<IUnitOfWork, UnitOfWork>();

En la carpeta Controllers creamos el controlador ProductsController

public class ProductsController : Controller


{
private readonly IProductService _productService;

public ProductsController(IProductService productService)


{
_productService = productService;
}

[HttpGet]
public async Task<IEnumerable<Productos>> ListAsync()
{
var result = await _productService.FindAllAsync();
return result;
}

[HttpPost]
public async Task<IActionResult> PostAsync([FromBody] Productos product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}

var result = await _productService.SaveAsync(product);

if (!result.IsSuccess())
{
return BadRequest(result as ErrorCRUDResponse);
}

return CreatedAtAction("Get", new { id = (result as


SuccessCRUDResponse).Data.Codigo }, product);
}

[HttpPut("{id}")]
public async Task<IActionResult> PutAsync(int id, [FromBody] Productos product)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}

var result = await _productService.UpdateAsync(id, product);

if (!result.IsSuccess())
{
var errorResponse = result as ErrorCRUDResponse;
if (errorResponse.status == 404)
{
return NotFound();
}
else
{
return BadRequest(errorResponse);
}
}

return Ok((result as SuccessCRUDResponse).Data);


}

[HttpGet("{id}")]
public ActionResult<Productos> Get(int id)
{
var result = _productService.FindById(id);

if (result == null)
{
return NotFound();
}

return result;
}

[HttpDelete("{id}")]
public async Task<ActionResult> DeleteAsync(int id)
{
var result = await _productService.DeleteAsync(id);

if (!result.IsSuccess())
{
return NotFound();
}

return NoContent();
}
}

S-ar putea să vă placă și