Skip to content

Instantly share code, notes, and snippets.

@dealproc
Last active August 29, 2015 14:13
Show Gist options
  • Save dealproc/3343ad429c0aa95df4ef to your computer and use it in GitHub Desktop.
Save dealproc/3343ad429c0aa95df4ef to your computer and use it in GitHub Desktop.
Full Duplex Routing
public class Customer : HQDataModelBase {
public virtual string FirstName { get; set; }
public virtual string LastName { get; set; }
public virtual string HomePhone { get; set; }
public virtual string MobilePhone { get; set; }
public virtual string BusinessPhone { get; set; }
public virtual string Email { get; set; }
public virtual Address Address { get; set; }
}
public abstract class DataModelBase : IEntity, INotifyPropertyChanged {
public DataModelBase() { }
public virtual int Id { get; set; }
public virtual DateTime CreatedOnUTC { get; set; }
public virtual DateTime UpdatedOnUTC { get; set; }
public virtual event PropertyChangedEventHandler PropertyChanged;
protected virtual void FirePropertyChanged(string p) {
var h = PropertyChanged;
if (h != null)
h(this, new PropertyChangedEventArgs(p));
}
}
namespace Adapt.POS.Store.DomainModel {
public abstract class DomainModelBase {
public string GUID { get; set; }
}
}
namespace Adapt.POS.Store.CloudConnect.DataModel {
public abstract class HQDataModelBase : DataModelBase {
public virtual string GUID { get; set; }
}
}
public abstract class DomainModelProxyHandler<TEntity, TModel> : IHQProxyHandler
where TEntity : HQDataModelBase, new()
where TModel : DomainModelBase {
protected readonly ILifetimeScope _LifetimeScope;
protected readonly string _EventName;
protected Func<IHubConnectionContext<dynamic>> _Workstations;
protected Func<IHubConnectionContext<dynamic>> _Dashboards;
protected readonly NLog.Logger _Log;
public DomainModelProxyHandler(ILifetimeScope lifetimeScope, string eventName) {
_LifetimeScope = lifetimeScope;
_EventName = eventName;
_Log = NLog.LogManager.GetCurrentClassLogger();
}
public virtual void RegisterEvents(Func<IHubConnectionContext<dynamic>> workstations, Func<IHubConnectionContext<dynamic>> dashboards, IHubProxy connectProxy) {
_Workstations = workstations;
_Dashboards = dashboards;
connectProxy.On<TModel, string>(_EventName, (model, action) => {
_Log.Debug("Event received: {0}", _EventName);
var actionType = ParseAction(action);
TModel wModel = default(TModel);
TEntity entity = default(TEntity);
using (var scope = _LifetimeScope.BeginLifetimeScope()) {
var repo = scope.Resolve<IRepository<TEntity>>();
var builder = scope.Resolve<IBuilder<TEntity, TModel>>();
switch (actionType) {
case ModelAction.Added:
case ModelAction.Updated:
entity = builder.BuildEntity(model, true);
var savedEntity = repo.SaveOrUpdate(entity);
wModel = builder.BuildViewModel(savedEntity);
break;
case ModelAction.Removed:
entity = repo.GetFirst(x => x.GUID == model.GUID);
if (entity == null) {
return;
}
wModel = builder.BuildViewModel(entity);
repo.Delete(entity);
break;
}
// inspired from: http://stackoverflow.com/questions/11042399/execute-method-on-dynamic
_Log.Debug("Issuing event: '{0}' with action: '{1}' to all workstations.", _EventName, action);
_Workstations.Invoke().All.Invoke(_EventName, wModel, action);
Upload(entity, action);
}
_Dashboards.Invoke().All.ObjectUpdated(string.Format("{0} has been {1} at {2}", entity.GetType().Name, action, DateTimeOffset.UtcNow));
});
}
public virtual void Upload(TEntity entity, string action) { }
protected ModelAction ParseAction(string actionName) {
switch (actionName.ToLower()) {
case "added":
return ModelAction.Added;
case "updated":
return ModelAction.Updated;
case "removed":
return ModelAction.Removed;
default:
return ModelAction.Updated;
}
}
}
public class FullDuplexDomainModelProxyHandler<TEntity, TModel> : DomainModelProxyHandler<TEntity, TModel>
where TEntity : DataModel.HQDataModelBase, new()
where TModel : DomainModel.DomainModelBase {
IHubProxy _ConnectProxy;
public FullDuplexDomainModelProxyHandler(ILifetimeScope lifetimeScope, string eventName)
: base(lifetimeScope, eventName) {
}
public override void RegisterEvents(Func<IHubConnectionContext<dynamic>> workstationConnections, Func<IHubConnectionContext<dynamic>> dashboardConnections, IHubProxy connectProxy) {
base.RegisterEvents(workstationConnections, dashboardConnections, connectProxy);
_ConnectProxy = connectProxy;
}
public async override void Upload(TEntity entity, string action) {
TModel model = default(TModel);
using (var scope = _LifetimeScope.BeginLifetimeScope()) {
var repo = scope.Resolve<IRepository<TEntity>>();
var builder = scope.Resolve<IBuilder<TEntity, TModel>>();
var dbEntity = repo.Get(entity.Id);
model = builder.BuildViewModel(dbEntity);
}
await _ConnectProxy.Invoke(_EventName, model, action);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment