This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using AutoMapper; | |
using Company.Application.Common.Paging; | |
using Company.Application.Common.Paging.Interface; | |
using Company.Application.Common.Repository; | |
using Company.Application.Common.UnitofWork; | |
using Microsoft.AspNetCore.Http; | |
using Microsoft.AspNetCore.Mvc; | |
using Microsoft.Extensions.DependencyInjection; | |
using Microsoft.Extensions.Logging; | |
using System; | |
using System.Collections.Generic; | |
using System.Linq; | |
using System.Threading.Tasks; | |
namespace Company.Application.Common.Api.Base | |
{ | |
public class ApiBase<T, TDto, TController> : ControllerBase where T : class where TDto : class where TController : ControllerBase | |
{ | |
#region Variables | |
/// <summary> | |
/// Sınıf içerisinde kullanacağımız değişkenlerimizi tanımlıyoruz. Unitofwork ve generic repository private yani sadece bu sınıf için erişilebilirken logger tüm sınıflardan erişilebilsin diye public bırakıyoruz. | |
/// Bu sınıfı kalıtım alan tüm sınırlarımızda loglama işlemi yapacağımız için logger public.. | |
/// </summary> | |
public readonly IUnitofWork _uow; | |
public readonly IServiceProvider _service; | |
public readonly ILogger<TController> _logger; | |
private readonly IGenericRepository<T> _repository; | |
#endregion Variables | |
#region Constructor | |
/// <summary> | |
/// Burada dependency injection'ı farklı şekilde kullanmaya karar verdim çünkü diğer projelerimde constructorlar içerisinde çok fazla parametre oluyor ve okunması zor hale geliyordu. | |
/// IserviceProvider benim için dependency injection ile resolve işlemi görecek yani bağımlılığı service provider ile projeme enjekte edeceğim. | |
/// </summary> | |
/// <param name="service">bağımlılıkları eklemek için service provider kullanacağız</param> | |
public ApiBase(IServiceProvider service) | |
{ | |
//Get Service diyerek dependencylerimizi ınject ediyoruz | |
_logger = service.GetService<ILogger<TController>>(); | |
_uow = service.GetService<IUnitofWork>(); | |
_repository = _uow.GetRepository<T>(); | |
_service = service; | |
} | |
#endregion Constructor | |
#region GetMethods | |
/// <summary> | |
/// Kayıtları veritabanından bulurken bu metodu kullanacağız. Bu method içerisine aranan kaydın Id bilgisini alacak ve geriye ilgili entity ile maplenmiş dto cevabını dönecek. | |
/// </summary> | |
/// <param name="id">bulunacak kaydın Guid türünde Id bilgisi</param> | |
/// <returns></returns> | |
[HttpGet("Find")] | |
public virtual ApiResult<TDto> Find(Guid id) | |
{ | |
try | |
{ | |
//Logger ile basit bir log yazıyoru. Ben logların mantıklı olması için zaman harcamadım siz senaryonuza göre loglamanıza karar verebilirsiniz. | |
//Burada sadece ilgili tablodan hangi id ye sahip kayıt istenmiş ise onu logluyoruz. | |
_logger.LogInformation($"Find record from the {typeof(T)} table with id:{id}"); | |
//Geriye Mapper ile mapleyerek dto dönüyoruz T bizim entitylerimiz için generic type ve TDto ise dto larımız için generic type görevi görüyor. | |
return new ApiResult<TDto> | |
{ | |
Message = "Success", | |
StatusCode = StatusCodes.Status200OK, | |
Data = Mapper.Map<T, TDto>(_repository.Find(id)) | |
}; | |
} | |
catch (Exception ex) | |
{ | |
//Hata olması durumunda loglama yapıyoruz ve kullanıcıya HTTP durum kodlarından 500 yani internal server error dönüyoruz. | |
_logger.LogError($"Find record error from the {typeof(T)} table with id:{id} error:{ex}"); | |
return new ApiResult<TDto> | |
{ | |
StatusCode = StatusCodes.Status500InternalServerError, | |
Message = $"Error:{ex.Message}", | |
Data = null | |
}; | |
} | |
} | |
[HttpGet("FindAsync")] | |
public virtual async Task<ApiResult<TDto>> FindAsync(Guid id) | |
{ | |
return Find(id); | |
} | |
/// <summary> | |
/// İlgili tabloda bulunan tüm kayıtları seçmek için kullanılacak olan metod | |
/// </summary> | |
/// <returns></returns> | |
[HttpGet("GetAll")] | |
public virtual ApiResult<List<TDto>> GetAll() | |
{ | |
try | |
{ | |
var entities = _repository.GetAll().ToList(); | |
_logger.LogInformation($"Getall records from the {typeof(T)} table"); | |
return new ApiResult<List<TDto>> | |
{ | |
Message = "Success", | |
StatusCode = StatusCodes.Status200OK, | |
Data = entities.Select(x => Mapper.Map<TDto>(x)).ToList() | |
}; | |
} | |
catch (Exception ex) | |
{ | |
_logger.LogError($"Getall records error from the {typeof(T)} table"); | |
return new ApiResult<List<TDto>> | |
{ | |
Message = $"Error:{ex.Message}", | |
StatusCode = StatusCodes.Status500InternalServerError, | |
Data = null | |
}; | |
} | |
} | |
/// <summary> | |
/// Sorgulanabilir ve üzerinde işlemler yapılabilir bir Queryable dönen metodumuz | |
/// Burada önemli nokta herhangi bir şekilde mapper ile işimiz yok direk olarak queryable donuyoruz. | |
/// </summary> | |
/// <returns></returns> | |
[HttpGet("GetQueryable")] | |
public virtual IQueryable<T> GetQueryable() | |
{ | |
try | |
{ | |
_logger.LogInformation($"GetQueryable from the {typeof(T)} table"); | |
return _repository.GetAll(); | |
} | |
catch (Exception Ex) | |
{ | |
_logger.LogError($"GetQueryable error from the {typeof(T)} table. Error:{Ex}"); | |
return null; | |
} | |
} | |
/// <summary> | |
/// Sayfalanmış listeler dönmek için kullanacağımız metot | |
/// </summary> | |
/// <param name="pagingParams">Hangi sayfa isteniyor ve sayfada kaç kayıt listelenecek gibi bilgileri parametre olarak bekler</param> | |
/// <returns></returns> | |
[HttpPost("GetAllWithPaging")] | |
public virtual ApiResult GetAllWithPaging(PagingParams pagingParams) | |
{ | |
try | |
{ | |
_logger.LogInformation($"GetAllWithPaging from the {typeof(T)} table"); | |
var pagingLinks = _service.GetService<IPagingLinks<T>>(); | |
var model = new PagedList<T>( | |
GetQueryable(), pagingParams.PageNumber, pagingParams.PageSize); | |
Response.Headers.Add("X-Pagination", model.GetHeader().ToJson()); | |
var outputModel = new OutputModel<T> | |
{ | |
Paging = model.GetHeader(), | |
Links = pagingLinks.GetLinks(model), | |
Items = model.List.Select(m => m).ToList(), | |
}; | |
return new ApiResult | |
{ | |
StatusCode = StatusCodes.Status200OK, | |
Message = "Success", | |
Data = outputModel | |
}; | |
} | |
catch (Exception ex) | |
{ | |
_logger.LogError($"GetAllWithPaging error from the {typeof(T)} table. Data: {String.Join(',', pagingParams.GetType().GetProperties().Select(x => $" - {x.Name} : {x.GetValue(pagingParams)} - ").ToList())} exception:{ex}"); | |
return new ApiResult | |
{ | |
StatusCode = StatusCodes.Status500InternalServerError, | |
Message = $"Error:{ex.Message}", | |
Data = null | |
}; | |
} | |
} | |
#endregion GetMethods | |
#region PostMethods | |
/// <summary> | |
/// Id ile Kayıt silmek için kullanacağımız metod | |
/// </summary> | |
/// <param name="id">Silinecek kaydın Id bilgisi</param> | |
/// <returns></returns> | |
[HttpPost("DeleteById")] | |
public virtual ApiResult<string> DeleteById(Guid id) | |
{ | |
try | |
{ | |
_repository.Delete(id); | |
_logger.LogInformation($"Record deleted from the {typeof(T)} table with id:{id}"); | |
return new ApiResult<string> | |
{ | |
StatusCode = StatusCodes.Status200OK, | |
Message = "Success", | |
Data = null | |
}; | |
} | |
catch (Exception ex) | |
{ | |
_logger.LogError($"Delete error for the:{typeof(T)} table with id:{id} result:Error - {ex}"); | |
return new ApiResult<string> | |
{ | |
StatusCode = StatusCodes.Status500InternalServerError, | |
Message = $"Error:{ex.Message}", | |
Data = null | |
}; | |
} | |
} | |
/// <summary> | |
/// Id ile Kayıt silmek için kullanacağımız metod | |
/// </summary> | |
/// <param name="id">Silinecek kaydın Id bilgisi</param> | |
/// <returns></returns> | |
[HttpPost("DeleteByIdAsync")] | |
public virtual async Task<ApiResult<string>> DeleteByIdAsync(Guid id) | |
{ | |
return DeleteById(id); | |
} | |
/// <summary> | |
/// Model ile kayıt silmek için kullanacağımız metod | |
/// </summary> | |
/// <param name="item">silinecek kayda ait model</param> | |
/// <returns></returns> | |
[HttpPost("Delete")] | |
public virtual ApiResult<string> Delete([FromBody] TDto item) | |
{ | |
var resolvedItem = String.Join(',', item.GetType().GetProperties().Select(x => $" - {x.Name} : {x.GetValue(item)} - ").ToList()); | |
try | |
{ | |
_repository.Delete(Mapper.Map<T>(item)); | |
_logger.LogInformation($"Record deleted from the {typeof(T)} table. Data:{resolvedItem}"); | |
return new ApiResult<string> | |
{ | |
StatusCode = StatusCodes.Status200OK, | |
Message = "Success", | |
Data = null | |
}; | |
} | |
catch (Exception ex) | |
{ | |
_logger.LogError($"Delete record error from the {typeof(T)} table. Data: {resolvedItem} exception:{ex}"); | |
return new ApiResult<string> | |
{ | |
StatusCode = StatusCodes.Status500InternalServerError, | |
Message = $"Error:{ex.Message}", | |
Data = null | |
}; | |
} | |
} | |
/// <summary> | |
/// Model ile kayıt silmek için kullanacağımız metod | |
/// </summary> | |
/// <param name="item">silinecek kayda ait model</param> | |
/// <returns></returns> | |
[HttpPost("DeleteAsync")] | |
public virtual async Task<ApiResult<string>> DeleteAsync([FromBody] TDto item) | |
{ | |
return Delete(item); | |
} | |
/// <summary> | |
/// Kayıt eklemek için metod | |
/// </summary> | |
/// <param name="item">Eklenecek kayıt</param> | |
/// <returns></returns> | |
[HttpPost("Add")] | |
public virtual ApiResult<TDto> Add([FromBody] TDto item) | |
{ | |
var resolvedItem = String.Join(',', item.GetType().GetProperties().Select(x => $" - {x.Name} : {x.GetValue(item)} - ").ToList()); | |
try | |
{ | |
var TResult = _repository.Add(Mapper.Map<T>(item)); | |
_logger.LogInformation($"Add record to the {typeof(T)} table. Data:{resolvedItem}"); | |
return new ApiResult<TDto> | |
{ | |
StatusCode = StatusCodes.Status200OK, | |
Message = "Success", | |
Data = Mapper.Map<T, TDto>(TResult) | |
}; | |
} | |
catch (Exception ex) | |
{ | |
_logger.LogError($"Add record error to the {typeof(T)} table. Data: {resolvedItem} exception:{ex}"); | |
return new ApiResult<TDto> | |
{ | |
StatusCode = StatusCodes.Status500InternalServerError, | |
Message = $"Error:{ex.Message}", | |
Data = null | |
}; | |
} | |
} | |
/// <summary> | |
/// Kayıt eklemek için metod | |
/// </summary> | |
/// <param name="item">Eklenecek kayıt</param> | |
/// <returns></returns> | |
[HttpPost("AddAsync")] | |
public virtual async Task<ApiResult<TDto>> AddAsync([FromBody] TDto item) | |
{ | |
return Add(item); | |
} | |
/// <summary> | |
/// Kayıt güncellemek için metod | |
/// </summary> | |
/// <param name="item"></param> | |
/// <returns></returns> | |
[HttpPost("Update")] | |
public virtual ApiResult<TDto> Update([FromBody] TDto item) | |
{ | |
var resolvedItem = String.Join(',', item.GetType().GetProperties().Select(x => $" - {x.Name} : {x.GetValue(item)} - ").ToList()); | |
try | |
{ | |
var TResult = _repository.Update(Mapper.Map<T>(item)); | |
_logger.LogInformation($"Update record to the {typeof(T)} table. Data:{resolvedItem}"); | |
return new ApiResult<TDto> | |
{ | |
StatusCode = StatusCodes.Status200OK, | |
Message = "Success", | |
Data = Mapper.Map<T, TDto>(TResult) | |
}; | |
} | |
catch (Exception ex) | |
{ | |
_logger.LogError($"Update record error to the {typeof(T)} table. Data: {resolvedItem} exception:{ex}"); | |
return new ApiResult<TDto> | |
{ | |
StatusCode = StatusCodes.Status500InternalServerError, | |
Message = $"Error:{ex.Message}", | |
Data = null | |
}; | |
} | |
} | |
/// <summary> | |
/// Kayıt güncellemek için metod | |
/// </summary> | |
/// <param name="item"></param> | |
/// <returns></returns> | |
[HttpPost("UpdateAsync")] | |
public virtual async Task<ApiResult<TDto>> UpdateAsync([FromBody] TDto item) | |
{ | |
return Update(item); | |
} | |
#endregion PostMethods | |
#region SaveChanges | |
/// <summary> | |
/// İşlemleri kaydedecek metot. Bu metot çağrılmaz ise işlemler veritabanına gitmeyecektir. | |
/// </summary> | |
private void Save() | |
{ | |
_uow.SaveChanges(true); | |
} | |
#endregion SaveChanges | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment