using System; using System.Collections.Generic; using Luticate2.Utils.Dbo.Basic; using Luticate2.Utils.Dbo.PaginatedRequest; using Luticate2.Utils.Dbo.Result; using Luticate2.Utils.Interfaces; using Luticate2.Utils.Utils; namespace Luticate2.Utils.Business { public abstract class LuCrudBusiness : LuBusiness, ILuCrudInterface where TDataAccess : ILuCrudInterface where TDboCreate : class where TDboRead : class where TDboUpdate : class { protected readonly TDataAccess DataAccess; protected readonly IServiceProvider ServiceProvider; private readonly IList _listeners = new List(); protected LuCrudBusiness(TDataAccess dataAccess, IServiceProvider serviceProvider) { DataAccess = dataAccess; ServiceProvider = serviceProvider; } public void AddListener() where T : ILuCrudNotifications { _listeners.Add(typeof(T)); } protected virtual LuResult CheckAdd(TDboCreate obj) { return LuResult.Ok(obj); } protected virtual LuResult CheckEdit(TDboRead dbo, TDboUpdate update) { return LuResult.Ok(update); } protected virtual LuResult GetAndCheckEdit(TId id, TDboUpdate update) { var res = GetSingleById(id); if (!res) { return res.To(); } return CheckEdit(res.Data, update); } public TId GetDboId(TDboRead obj) { return DataAccess.GetDboId(obj); } public virtual LuResult Add(TDboCreate obj, Func returnFunc) { var res = CheckAdd(obj); if (!res) { return res.To(); } var newEntity = DataAccess.AddDbo(res.Data); if (newEntity) { NotifyCreate(newEntity.Data); return LuResult.Ok(returnFunc(newEntity.Data)); } return newEntity.To(); } public virtual LuResult GetSingleById(TId id) { return DataAccess.GetSingleById(id); } public virtual LuResult> GetMultiple(LuPaginatedRequestDbo request) { return DataAccess.GetMultiple(request); } public virtual LuResult EditSingleById(TId id, TDboUpdate update, Func returnFunc) { var originalEntity = GetSingleById(id); if (!originalEntity) { return originalEntity.To(); } var obj = CheckEdit(originalEntity.Data, update); if (!obj) { return obj.To(); } var editedEntity = DataAccess.EditSingleByIdDbo(id, obj.Data); if (editedEntity) { NotifyUpdate(originalEntity.Data, editedEntity.Data); return LuResult.Ok(returnFunc(editedEntity.Data)); } return editedEntity.To(); } public virtual LuResult DeleteSingleById(TId id, Func returnFunc) { var originalEntity = GetSingleById(id); if (!originalEntity) { return originalEntity.To(); } var res = DataAccess.DeleteSingleById(id, returnFunc); if (res) { NotifyDelete(originalEntity.Data); } return res; } private void ForeachListener(Action action) { foreach (var listener in _listeners) { var instance = ServiceProvider.GetService(listener) as ILuCrudNotifications; action(instance); } } private void NotifyCreate(object newEntity) { ForeachListener(notifications => notifications.NotifyCreate(GetType(), newEntity)); } private void NotifyUpdate(object oldEntity, object newEntity) { ForeachListener(notifications => notifications.NotifyUpdate(GetType(), oldEntity, newEntity)); } private void NotifyDelete( object oldEntity) { ForeachListener(notifications => notifications.NotifyDelete(GetType(), oldEntity)); } } }