Last active
January 8, 2021 10:07
-
-
Save tim-elvidge/e9832448a3cddfc60adc to your computer and use it in GitHub Desktop.
Generic Mediator Pattern for Data Handling
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
public partial class AuctionUsersController : WebCommon.Controllers.DapperGridController<Domain.AuctionModels.UserDto> | |
{ | |
public AuctionUsersController(IDbInterface mediatorInjection) | |
{ | |
base.DbMediator = mediatorInjection; | |
} | |
public virtual ActionResult Index() | |
{ | |
return View(); | |
} | |
} |
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
public abstract class Crud<Data> | |
{ | |
public Data Param { get; set; } | |
public IModelStateDictionary ModelState { get; set; } | |
public IdentityModels.IAppUser CurrentUser { get; set; } | |
} | |
public class Create<Data> : Crud<Data> | |
{ | |
public Create(Data param, IModelStateDictionary modelState, IdentityModels.IAppUser currentUser) | |
{ | |
this.Param = param; | |
this.ModelState = modelState; | |
this.CurrentUser = currentUser; | |
} | |
} | |
public class Delete<Data> : Crud<Data> | |
{ | |
public Delete(Data param, IModelStateDictionary modelState, IdentityModels.IAppUser currentUser) | |
{ | |
this.Param = param; | |
this.ModelState = modelState; | |
this.CurrentUser = currentUser; | |
} | |
} | |
public class Update<Data> : Crud<Data> | |
{ | |
public Update(Data param, IModelStateDictionary modelState, IdentityModels.IAppUser currentUser) | |
{ | |
this.Param = param; | |
this.ModelState = modelState; | |
this.CurrentUser = currentUser; | |
} | |
} | |
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
public class DbInterface: IDbInterface | |
{ | |
internal readonly IMediator DbMediator; | |
public DbInterface(IMediator mediatorInjection) | |
{ | |
DbMediator = mediatorInjection; | |
} | |
public Data Request<Data>(Get<Data> param) | |
{ | |
return DbMediator.Send(new Request<Data>()); | |
} | |
public Data Request<Data, Params>(Get<Data>.Where<Params> param) | |
{ | |
return DbMediator.Send(new Request<Data>.Where<Params>(param.Request)); | |
} | |
public async Task<Data> RequestAsync<Data>(Get<Data> param) | |
{ | |
return await DbMediator.SendAsync(new RequestAsync<Data>()); | |
} | |
public async Task<Data> RequestAsync<Data, Params>(Get<Data>.Where<Params> param) | |
{ | |
return await DbMediator.SendAsync(new RequestAsync<Data>.Where<Params>(param.Request)); | |
} | |
public bool Request<Data>(Crud<Data> param) | |
{ | |
DtoResult result = null; | |
if (param.GetType() == typeof(Create<Data>)) | |
{ | |
result = DbMediator.Send(new Request<DtoResult>.Where<Create<Data>>(param as Create<Data>)); | |
} | |
else if (param.GetType() == typeof(Update<Data>)) | |
{ | |
result = DbMediator.Send(new Request<DtoResult>.Where<Update<Data>>(param as Update<Data>)); | |
} | |
else | |
{ | |
result = DbMediator.Send(new Request<DtoResult>.Where<Delete<Data>>(param as Delete<Data>)); | |
} | |
return result.Success; | |
} | |
public async Task<bool> RequestAsync<Data>(Crud<Data> param) | |
{ | |
DtoResult result = null; | |
if (param.GetType() == typeof(Create<Data>)) | |
{ | |
result = await DbMediator.SendAsync(new RequestAsync<DtoResult>.Where<Create<Data>>(param as Create<Data>)); | |
} | |
else if (param.GetType() == typeof(Update<Data>)) | |
{ | |
result = await DbMediator.SendAsync(new RequestAsync<DtoResult>.Where<Update<Data>>(param as Update<Data>)); | |
} | |
else | |
{ | |
result = await DbMediator.SendAsync(new RequestAsync<DtoResult>.Where<Delete<Data>>(param as Delete<Data>)); | |
} | |
return result.Success; | |
} | |
public void Execute<Params>(Params param) | |
{ | |
DbMediator.Send(new Request<Unit>.Where<Params>(param)); | |
} | |
public async Task ExecuteAsync<Params>(Params param) | |
{ | |
await DbMediator.SendAsync(new RequestAsync<Unit>.Where<Params>(param)); | |
} | |
} |
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
public class Request<Response> : MediatR.IRequest<Response> | |
{ | |
public partial class Where<Params> : MediatR.IRequest<Response> | |
{ | |
public Params Request { get; set; } | |
public Where(Params param) | |
{ | |
this.Request = param; | |
} | |
} | |
} |
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
public interface IDbInterface | |
{ | |
Data Request<Data>(Get<Data> param); | |
Data Request<Data, Params>(Get<Data>.Where<Params> param); | |
Task<Data> RequestAsync<Data>(Get<Data> param); | |
Task<Data> RequestAsync<Data, Params>(Get<Data>.Where<Params> param); | |
bool Request<Data>(Crud<Data> param); | |
Task<bool> RequestAsync<Data>(Crud<Data> param); | |
void Execute<Params>(Params request); | |
Task ExecuteAsync<Params>(Params request); | |
} |
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
public abstract partial class DapperGridController<Dto> : AppController | |
where Dto : class | |
{ | |
public virtual IDbInterface DbMediator { get; set; } //Injected by concrete constructor | |
[AcceptVerbs(HttpVerbs.Post)] | |
public async virtual Task<ActionResult> GridReadAsync([DataSourceRequest] DataSourceRequest request) | |
{ | |
var result = (await DbMediator.RequestAsync(new Get<KendoDataSourceResult<Dto>>.Where<DapperDataSourceRequest>(new DapperDataSourceRequest(request)))).DataSourceResult as DataSourceResult; | |
return Json(result); | |
} | |
[AcceptVerbs(HttpVerbs.Post)] | |
public async virtual Task<ActionResult> GridReadByIDAsync(int? id, [DataSourceRequest] DataSourceRequest request) | |
{ | |
var result = (await DbMediator.RequestAsync(new Get<KendoDataSourceResult<Dto>>.Where<DapperDataSourceRequest<int>>(new DapperDataSourceRequest<int>(request, (id == null ? 0 : (int)id))))).DataSourceResult as DataSourceResult; | |
return Json(result); | |
} | |
[AcceptVerbs(HttpVerbs.Post)] | |
public virtual ActionResult GridCreate([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = Globals.Constants.Models)]IEnumerable<Dto> dtos) | |
{ | |
DbMediator.Request(new Create<IEnumerable<Dto>>(dtos, new MvcModelStateDictionary(ModelState), CurrentUser)); | |
return Json(dtos.ToDataSourceResult(request, ModelState)); | |
} | |
[AcceptVerbs(HttpVerbs.Post)] | |
public virtual ActionResult GridUpdate([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = Globals.Constants.Models)]IEnumerable<Dto> dtos) | |
{ | |
DbMediator.Request(new Update<IEnumerable<Dto>>(dtos, new MvcModelStateDictionary(ModelState), CurrentUser)); | |
return Json(dtos.ToDataSourceResult(request, ModelState)); | |
} | |
[AcceptVerbs(HttpVerbs.Post)] | |
public virtual ActionResult GridDestroy([DataSourceRequest] DataSourceRequest request, [Bind(Prefix = Globals.Constants.Models)]IEnumerable<Dto> dtos) | |
{ | |
DbMediator.Request(new Delete<IEnumerable<Dto>>(dtos, new MvcModelStateDictionary(ModelState), CurrentUser)); | |
return Json(dtos.ToDataSourceResult(request, ModelState)); | |
} | |
} |
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
public abstract partial class DtoHandler<TEntity, Dto> : | |
IRequestHandler<Request<DtoResult>.Where<Create<Dto>>, DtoResult>, | |
IRequestHandler<Request<DtoResult>.Where<Update<Dto>>, DtoResult>, | |
IRequestHandler<Request<DtoResult>.Where<Delete<Dto>>, DtoResult> | |
where TEntity : class | |
where Dto : class | |
{ | |
public virtual Entities Db {get; set;} | |
public virtual DataAccess.OnAdd<TEntity, Dto> OnAdd { get; set; } | |
public virtual DataAccess.OnChange<TEntity, Dto> OnChange { get; set; } | |
DtoResult IRequestHandler<Request<DtoResult>.Where<Create<Dto>>, DtoResult>.Handle(Request<DtoResult>.Where<Create<Dto>> query) | |
{ | |
var response = DtoResult.Create(); | |
response.Success = DataAccess.AddChanges<TEntity, Dto>(Db, query.Request.ModelState, query.Request.Param, OnAdd, query.Request.CurrentUser); | |
return response; | |
} | |
DtoResult IRequestHandler<Request<DtoResult>.Where<Update<Dto>>, DtoResult>.Handle(Request<DtoResult>.Where<Update<Dto>> query) | |
{ | |
var response = DtoResult.Create(); | |
response.Success = DataAccess.SaveChanges<TEntity, Dto>(Db, query.Request.ModelState, query.Request.Param, OnChange, query.Request.CurrentUser); | |
return response; | |
} | |
DtoResult IRequestHandler<Request<DtoResult>.Where<Delete<Dto>>, DtoResult>.Handle(Request<DtoResult>.Where<Delete<Dto>> query) | |
{ | |
var response = DtoResult.Create(); | |
response.Success = DataAccess.Delete<TEntity, Dto>(Db, query.Request.ModelState, query.Request.Param, query.Request.CurrentUser); | |
return response; | |
} | |
} |
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
var qry = DbMediator.Request(new Get<IQueryable<Domain.AdminModels.CategoryDto>>()).ProjectTo<Domain.CommonModels.LookupCategorys>(); | |
var newCategory = new Domain.AdminModels.CategoryDto(); | |
newCategory.Description = category; | |
var createIt = DbMediator.Request(new Create<Domain.AdminModels.CategoryDto>(newCategory, new WebCommon.MvcModelStateDictionary(ModelState), CurrentUser)); | |
var dto = DbMediator.Request(new Get<Domain.AdminModels.ClientDto>.Where<int>(id)); | |
var products = (await dbMediator.RequestAsync(new Get<KendoDataSourceResult<Domain.AdminModels.ProductsDto>>.Where<DapperDataSourceRequest<ProductsDataSourceRequest>>(new DapperDataSourceRequest<ProductsDataSourceRequest>(request,dsParam)))).DataSourceResult as DataSourceResult; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Expanding on the fantastic ideas of Jimmy Bogard using the CQRS system using the Mediator pattern