Skip to content

Instantly share code, notes, and snippets.

@tim-elvidge
Last active January 8, 2021 10:07
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tim-elvidge/e9832448a3cddfc60adc to your computer and use it in GitHub Desktop.
Save tim-elvidge/e9832448a3cddfc60adc to your computer and use it in GitHub Desktop.
Generic Mediator Pattern for Data Handling
public partial class AuctionUsersController : WebCommon.Controllers.DapperGridController<Domain.AuctionModels.UserDto>
{
public AuctionUsersController(IDbInterface mediatorInjection)
{
base.DbMediator = mediatorInjection;
}
public virtual ActionResult Index()
{
return View();
}
}
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;
}
}
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));
}
}
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;
}
}
}
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);
}
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));
}
}
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;
}
}
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;
@tim-elvidge
Copy link
Author

Expanding on the fantastic ideas of Jimmy Bogard using the CQRS system using the Mediator pattern

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment