我研究了一些CQRS样本实现(Java/.Net),它们使用事件源作为事件存储,使用简单(No)SQL存储作为"报告存储".
看起来很好,但我似乎在所有示例实现中都缺少某些东西.
在应用程序投入生产后,如何处理新报表存储/屏幕的添加?以及如何将现有(最新)数据从事件存储导入新报表存储?
即:
想象一下基本的DDD/CQRS驱动的CRM应用程序.每个屏幕(真的查看)都有自己的结构化报表存储(SQL表).所有这些视图都使用侦听域事件(CustomerCreated/CustomerHasMoved等)的处理程序进行更新.
CRM的一个特点是它可以记录电话呼叫(PhoneCallLogged事件).由于时间限制,我们只在CRM的V1中实现了电话呼叫的记录(查看和报告谁处理了哪个电话将在V2中实施)
在生产中运行一段时间后,我们希望实现每个客户和销售代表记录的电话呼叫的"报告".
因此,我们需要添加一些屏幕(视图)和支持报告表(在报告存储中),并用事件存储中已收集的数据填充它...
这是我在看我研究的样品时卡住的地方.它们不处理将现有(历史)数据从事件存储导入(新)报表存储.
EventRepository(DomainRepository)的所有示例只有一个方法'GetById'和'Add',它们不支持一次性获取所有聚合根以填充新的报告表.
如果没有初始数据导入,新屏幕仅针对新发生的事件进行更新.不适用于已记录的电话(因为没有PhoneCallLogged事件的报告侦听器)
有什么建议,建议吗?
提前致谢,
REMCO
解析Windsor容器找不到的组件时,会抛出异常.
StructureMap有一个TryGetInstance方法,它返回null无法找到所请求的组件.
Castle Windsor有这样的吗?或者我被迫捕获这些异常(我不喜欢这样,因为抛出和捕获异常的性能开销).
提前致谢,
REMCO
我目前正在开发一个自定义的HttpHandler(用于压缩/组合CSS,但这对于这个问题无关紧要).
我从一个简单的reusable = true同步HttpHandler开始,就像我们都知道的那样.
现在我正在尝试将其改进为异步处理程序(因为它使用IO功能并且它在非常繁忙的网站上使用).
我的第一次尝试(这似乎工作正常):
Action<HttpContext> asyncProcessRequest;
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
asyncProcessRequest = new Action<HttpContext>(ProcessRequest);
return asyncProcessRequest.BeginInvoke(context, cb, extraData);
}
public void EndProcessRequest(IAsyncResult result)
{
asyncProcessRequest.EndInvoke(result);
}
public virtual void ProcessRequest(HttpContext context)
{
// real work
}
Run Code Online (Sandbox Code Playgroud)
这是一个不可重用的httphandler(从我读到的,IsReusable应该是false,因为这个处理程序有状态(asyncProcessRequest字段).
现在我想让它重复使用.所以我的第一个想法是创建一个IAsyncResult/Action字典,如下所示:
IDictionary<IAsyncResult, Action<HttpContext>> asyncProcessRequests;
public IAsyncResult BeginProcessRequest(HttpContext context, AsyncCallback cb, object extraData)
{
if (asyncProcessRequests == null)
{
asyncProcessRequests = new Dictionary<IAsyncResult, Action<HttpContext>>();
}
var request = new Action<HttpContext>(ProcessRequest);
var result = request.BeginInvoke(context, cb, extraData);
asyncProcessRequests.Add(result, …Run Code Online (Sandbox Code Playgroud) 所以我注意到淘汰js与jQuery jwysiwyg插件不兼容.
阅读这篇博客后:http://www.knockmeout.net/2011/07/another-look-at-custom-bindings-for.html 这SO回答:如何检测到的内容与jQuery的变化使用jWYSIWYG插件的textarea?
我编写了以下绑定处理程序:
ko.bindingHandlers.wysiwyg = {
init: function (element, valueAccessor, allBindingsAccessor) {
var options = allBindingsAccessor().wysiwygOptions || {};
var value = ko.utils.unwrapObservable(valueAccessor());
var $e = $(element);
$.extend(true, {
initialContent : value
}, options);
$e.wysiwyg(options);
//handle the field changing
function detectFn() {
var observable = valueAccessor();
var newvalue = $e.wysiwyg("getContent");
observable(newvalue);
}
var current = $e.wysiwyg('document');
var timer;
current.bind({
keyup: function(){
clearTimeout(timer);
timer = setTimeout(detectFn, 1000);
}
});
//handle disposal (if KO removes by the template binding) …Run Code Online (Sandbox Code Playgroud) 当我执行以下查询时,我得到一个异常,告诉我'feedItemQuery'包含多个项目(因此SingleOrDefault不起作用).
当使用Criteria api而没有DistinctRootEntity转换器时,这是预期的行为,但是当使用linq时,我希望得到一个单一的根实体(FeedItem,其属性Ads(of ICollection)包含所有广告).
有没有办法告诉NHibernate.Linq使用DistinctRootEntity转换器?
我的查询:
var feedItemQuery = from ad in session.Linq<FeedItem>().Expand("Ads")
where ad.Id == Id
select ad;
var feedItem = feedItemQuery.SingleOrDefault(); // This fails !?
Run Code Online (Sandbox Code Playgroud)
映射:
<class name="FeedItem" table="FeedItems" proxy="IFeedItem">
<id name="Id" type="Guid">
<generator class="guid.comb"></generator>
</id>
...
<set name="Ads" table="Ads">
<key column="FeedItemId" />
<one-to-many class="Ad" />
</set>
</class>
Run Code Online (Sandbox Code Playgroud)
提前致谢
c# ×2
.net ×1
asp.net ×1
asynchronous ×1
cqrs ×1
html ×1
httphandler ×1
javascript ×1
jwysiwyg ×1
knockout.js ×1
linq ×1
nhibernate ×1