NejCommon.NET/Controllers/AutoChildController.cs

111 lines
4.2 KiB
C#

using System.Linq.Expressions;
using System.Reflection;
using ApiSourceGeneratorHelper;
using AutoMapPropertyHelper;
using EntityFrameworkCore.Projectables;
using EntityFrameworkCore.Projectables.Extensions;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NejCommon.Utils;
using Swashbuckle.AspNetCore.Annotations;
using NejCommon.Models;
using System.ComponentModel.DataAnnotations.Schema;
namespace NejCommon.Controllers
{
public abstract class AutoChildController<TOwner, TType, TRequest, TResponse> : AutoChildController<TOwner, TType, TResponse, TRequest, TResponse>
where TType : class, new()
where TRequest : class, IAutomappedAttribute<TType, TRequest>, new()
where TResponse : class, IAutomappedAttribute<TType, TResponse>, new()
{
public AutoChildController(CommonDbContext appDb, IServiceProvider providers) : base(appDb, providers)
{
}
}
/// <summary>
///
/// </summary>
/// <typeparam name="TType">The underyling type</typeparam>
/// <typeparam name="TRequest">The request type</typeparam>
/// <typeparam name="TResponse">The response type</typeparam>
[ApiController]
public abstract class AutoChildController<TOwner, TType, TGetResponse, TUpdateRequest, TUpdateResponse> : ControllerBase
where TType : class, new()
where TGetResponse : class, IAutomappedAttribute<TType, TGetResponse>, new()
where TUpdateRequest : class, IAutomappedAttribute<TType, TUpdateRequest>, new()
where TUpdateResponse : class, IAutomappedAttribute<TType, TUpdateResponse>, new()
{
protected readonly CommonDbContext db;
protected readonly IServiceProvider providers;
public AutoChildController(CommonDbContext appDb, IServiceProvider providers) : base()
{
db = appDb;
this.providers = providers;
}
[NonAction]
public abstract TType? GetQuery(TOwner comp);
protected abstract void Assign(TOwner comp, TType query);
public virtual bool Trackable => true;
[NonAction]
public virtual TType GetQueryHelper(TOwner owner){
var entity = GetQuery(owner);
if (entity == null)
{
if (Trackable)
entity = db.Create<TType>();
else
entity = new TType();
Assign(owner, entity);
}
return entity;
}
/// <summary>
/// Gets the <typeparamref name="TType"/>
/// </summary>
/// <param name="entity"></param>
/// <response code="200">Success</response>
/// <response code="0">There was an error</response>
[HttpGet]
[Route("")]
public virtual async Task<Results<NotFound, Ok<TGetResponse>>> Get([FromServices] TOwner owner)
{
var entity = GetQuery(owner);
var dat = new TGetResponse().ApplyFrom(providers, entity);
return TypedResults.Ok(dat);
}
/// <summary>
/// Update company.
/// </summary>
/// <param name="entity"></param>
/// <param name="body"></param>
/// <response code="200">Success</response>
/// <response code="0">There was an error</response>
[HttpPut]
[Route("")]
public virtual async Task<Results<NotFound, BadRequest<Error>, Ok<TUpdateResponse>>> Update([FromServices] TOwner owner, [FromBody] TUpdateRequest body)
{
var entity = GetQueryHelper(owner);
/*
if(entity is InvoiceBase inv){
//Console.Writeline(inv.InvoiceItems.Count);
}*/
body.ApplyTo(providers, entity);
var res = await db.ApiSaveChangesAsyncOk<TType, TUpdateResponse>(providers, entity);
//use the private constructor thru reflection
var ctor = typeof(Results<NotFound, BadRequest<Error>, Ok<TUpdateResponse>>).GetConstructors(BindingFlags.NonPublic | BindingFlags.Instance)[0];
return (Results<NotFound, BadRequest<Error>, Ok<TUpdateResponse>>)ctor.Invoke(new object[] { res.Result });
}
}
}