嗨我正在使用IoC容器,我想在构造函数中初始化一个服务(其中一部分涉及'繁重的工作'与数据库交谈).
此特定服务存储由注入IPluginToServiceProviderBridge服务找到的信息,此信息通过a保存在数据库中UnitOfWork.
一旦所有内容都启动,带有命令的控制器和带有处理程序的服务将用于所有其他交互.所有命令都包含在生命周期范围内,因此保存和处理UnitOfWork是由处理程序而不是服务完成的(这对于干净的代码非常有用).
保存和事务的相关整洁和关注分离不适用于Initializer服务内部,因为一切都发生在构造函数中:
public PluginManagerService(
IPluginToServiceProviderBridge serviceProvider,
IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;
this.serviceProvider = serviceProvider;
lock (threadLock)
{
if (initialised == false)
{
LinkPluginsWithDatabase();
initialised = true;
}
// I don't like this next line, but
// not sure what else to do
this.UnitOfWork.Save();
}
}
protected void LinkPluginsWithDatabase()
{
var plugins =
this.serviceProvider.GetAllPlugins();
foreach (var plugin in plugins)
{
var db = new PluginRecord
{
interfaceType = plugin.InterfaceType;
var …Run Code Online (Sandbox Code Playgroud) 在此处查看演示CQRS代码,命令和事件处理程序分别连接如下:
public interface CommandHandler<in T>
{
void Handle(T command);
}
public interface EventHandler<in T>
{
void Handle(T @event);
}
bus = BusSetup.StartWith<Conservative>()
.Apply<FlexibleSubscribeAdapter>(a =>
{
a.ByInterface(typeof(IHandleEvent<>));
a.ByInterface(typeof(IHandleCommand<>));
})
.Construct();
Run Code Online (Sandbox Code Playgroud)
我正在使用一个与membus挂钩的IoC容器,它通过实现IEnumerable<object> GetAllInstances(Type desiredType)与容器的接口实现梦想,但是与使用这种注册方法的演示不同,我无法拆分单独命令和事件的接口:
this.Bus = BusSetup.StartWith<Conservative>()
.Apply <IoCSupport>(c =>
{
c
.SetAdapter(SimpleInjectorWiring.Instance)
.SetHandlerInterface(typeof(CommandHandler<>))
/*.SetHandlerInterface(typeof(EventHandler<>))*/;
// only CommandHandler or EventHandler can be used - not both
})
.Construct();
Run Code Online (Sandbox Code Playgroud)
任何人都可以告诉我,如果有任何方法,所以我们可以注册任意数量的类型?
我正在使用MVC4并通过nuget添加了Bootstrap和Font Awesome.
我可以看到Bootstrap如何捆绑在via BootstrapBundleConfig.cs(由nuget包添加)下面:
public static void RegisterBundles()
{
BundleTable.Bundles.Add(new ScriptBundle("~/bundles/bootstrap").Include("~/Scripts/bootstrap*"));
BundleTable.Bundles.Add(new StyleBundle("~/Content/bootstrap").Include("~/Content/bootstrap.css", "~/Content/bootstrap-responsive.css"));
}
Run Code Online (Sandbox Code Playgroud)
我有以下问题:
<link href="~/Content/font-awesome.min.css" rel="stylesheet" />- 正确的方法是什么?Include("~/Content/bootstrap.css", "~/Content/bootstrap-responsive.css"))?我正在创建一个签出流程,其中一步涉及配置产品.用例如下:
产品配置
产品配置是一组可配置的选项组.
选项组
每个选项组可以包含一个选定的选项(或者不包含),该组包含多个选项.
用户可以添加和删除产品组中的选项.
例如,选项组可以称为数据库.
选项
选项是选项组的特定选项.
作为属于数据库选项组的选项的示例,特定选项可以是MySQL或MS-SQL.
选项组依赖关系 选项组可以依赖于另一个选项组,以便在不满足目标选项组的要求时过滤掉特定项.
只有一个目标依赖项,我们不需要担心指向多个目标产品选项组的产品选项组中的选项.
例如,为了允许在数据库产品组中选择MS-SQL选项,必须从"操作系统"选项组中选择Windows选项.
同样,为了允许在数据库产品组上选择MySQL选项,必须从"操作系统"选项组中选择Windows或Linux选项.
结构体

在上图中,MySQL(ID = 201)产品选项依赖于OS产品选项组的Windows(ID = 101)或Linux(ID = 102)产品选项.如果选择了这些操作系统选项中的任何一个,则会显示MySQL.
MS-SQL(ID = 202)产品选项依赖于OS产品选项组的Windows(ID = 101)产品选项.仅在选择Windows操作系统时才会显示MS-SQL.
问题 - 存储依赖关系映射数据的位置?
现在随着代码的发展,问题在于存储产品选项与其组之间的关系依赖关系映射.我质疑的主要问题是:
单独聚合,管理交易
我们是否将映射存储在自己的聚合中,如果是这样,我们如何检测并停止删除被引用的Products和ProductOptionGroup?
例如,如果操作系统Windows存在依赖关系,我们必须保护它,如果其他OptionGroup依赖于它,则不允许从OS ProductOptionGroup中删除它.
这是由应用程序服务完成的吗?如何在我们的代码中构建一个事务?
内部聚合,更容易的事务管理,更高的并发问题的可能性
我们是否将映射存储在OptionGroup聚合中,但是如果我们这样做,如果有人更新了OptionGroup的名称和描述,而另一个用户正在编辑映射数据,则提交时会出现并发异常.
这没有多大意义,因为如果有人更新名称,映射数据不会失败,它们是两个不相关的概念.
在这种情况下,其他人会怎么做?我将如何最好地构建上述场景的代码?或者我错过了一些更深入的见解,从我的聚合中盯着我,如果重新设计会让事情变得更容易.
我认为DDD设计禁止从外部访问ProductOptionGroup内的ProductOptions,但我不能想到如何在此时以任何其他方式对其进行建模.
编辑Giacomo Tesio提出的答案
感谢您提出的答案并花时间提供帮助.我真的很喜欢整洁简洁的编码风格.你的回答确实提出了一些进一步的问题,如下所示,我可能正在咆哮错误的树,但希望澄清:
在OptionGroup,有一个_descriptions字典,这用于包含选项的描述.
为什么选项描述属性不是Option对象的一部分?
你提到的Option是一个值对象.
在这种情况下,它有一个名为_idtype 的成员OptionIdentity,是否允许值对象具有标识ID?
在代码中Option,它需要一个构造函数id和列表dependencies.
据我所知的Option仅存在作为一个部分OptionGroup(作为OptionIdentity类型需要构件_group类型的OptionGroupIdentity).是否Option允许一个 …
我正在使用一个控制台应用程序,我有 20 个需要读取的 URI 的批次,我发现通过执行所有任务并并行运行它们然后在不同的线程中对完成的结果进行排序(允许下一个要提取的批次)。
在我当前使用的调用中,每个线程在获取响应流时都会阻塞,我还看到有一个相同方法的异步版本GetResponseAsync。
我知道通过在同一行中使用 async Await 和 Async而不是阻塞来释放线程池有好处:
异步版本
return Task.Run(async () =>
{
var uri = item.Links.Alternate();
var request = (HttpWebRequest)WebRequest.Create(uri);
var response = await request.GetResponseAsync();
var stream = response.GetResponseStream();
if (stream == null) return null;
var reader = new StreamReader(stream);
return new FetchItemTaskResult(reader.ReadToEnd(), index, uri);
});
Run Code Online (Sandbox Code Playgroud)
屏蔽版本
return Task<FetchItemTaskResult>.Factory.StartNew(() =>
{
var uri = item.Links.Alternate();
var request = (HttpWebRequest)WebRequest.Create(uri);
var response = request.GetResponse();
var stream = response.GetResponseStream();
if (stream == …Run Code Online (Sandbox Code Playgroud) 我有以下课程,我试图补充:
public class Product
{
public readonly Sku Sku;
public string Name { get; private set; }
public string Description { get; private set; }
public bool IsArchived { get; private set; }
public Product(Sku sku, string name, string description, bool isArchived)
{
Sku = sku;
Name = name;
Description = description;
IsArchived = isArchived;
}
}
Run Code Online (Sandbox Code Playgroud)
其中使用以下类来实现我的DDD实体域模型中的概念(删除非相关代码以保持代码简短,设置为只读以在构造后使不可变):
public class Sku
{
public readonly VendorId VendorId;
public readonly string SkuValue;
public Sku(VendorId vendorId, string skuValue)
{
VendorId = vendorId;
SkuValue …Run Code Online (Sandbox Code Playgroud) 我编写了一个Event Sourced Aggregate,现在实现了一个Event Sourced Saga ......我注意到这两个是similair并创建了一个事件源对象作为基类,两者都是从这个派生出来的.
我在http://blog.jonathanoliver.com/cqrs-sagas-with-event-sourcing-part-ii-of-ii/看到了一个演示,但觉得可能存在一个问题,因为命令可能会丢失由于发送命令在写入事务之外,进程崩溃了吗?
public void Save(ISaga saga)
{
var events = saga.GetUncommittedEvents();
eventStore.Write(new UncommittedEventStream
{
Id = saga.Id,
Type = saga.GetType(),
Events = events,
ExpectedVersion = saga.Version - events.Count
});
foreach (var message in saga.GetUndispatchedMessages())
bus.Send(message); // can be done in different ways
saga.ClearUncommittedEvents();
saga.ClearUndispatchedMessages();
}
Run Code Online (Sandbox Code Playgroud)
相反,我正在使用Greg Young的EventStore,当我保存EventSourcedObject(聚合或传奇)时,序列如下:
我正在实现一个传奇的两个方面:
问题
据我所知,事件处理程序不应该发出命令(如果命令失败会发生什么?) - 但我对上面的确定,因为Saga是通过此事件代理控制命令创建(对事件做出反应)的实际操作,并且任何命令发送失败都可以在外部处理(在外部EventHandler处理,CommandEmittedFromSaga如果命令失败则重新发送)? …
我遇到了保护一个类的问题,该类由一个复合ID组成,而该复合ID又有一个基类,我收到一个错误说法 InvalidOperationException: {document}.Identity is not supported.
我试图写入数据库的类如下:
public class Product : IEntity<Product>
{
public readonly Sku Sku;
public string Name { get; private set; }
public string Description { get; private set; }
public bool IsArchived { get; private set; }
public Identity<Product> Identity => Sku;
public Product(Sku sku, string name, bool isArchived)
{
Sku = sku;
Name = name;
IsArchived = isArchived;
}
}
public interface IEntity<T>
{
Identity<T> Identity { get; }
}
Run Code Online (Sandbox Code Playgroud)
反过来有一个ID Sku,它是由下面的复合值(VendorId和一个本地 …
我有一个测试应用程序(首先使用RabbitMQ),它运行在部分受信任的客户端上(因为我不希望它们自己创建队列),所以我将查看客户端连接的队列和凭据的安全权限.
对于消息传递,主要是从服务器到客户端的单向广播,有时是从服务器到特定客户端的查询(回复将通过replyTo队列发送,该队列专用于服务器侦听响应的客户端) .
我目前在服务器上有一个接收功能,它寻找客户的"宣布"广播:
agentAnnounceListener.Received += (model, ea) =>
{
var body = ea.Body;
var props = ea.BasicProperties;
var message = Encoding.UTF8.GetString(body);
Console.WriteLine(
"[{0}] from: {1}. body: {2}",
DateTimeOffset.FromUnixTimeMilliseconds(ea.BasicProperties.Timestamp.UnixTime).Date,
props.ReplyTo,
message);
// create return replyTo queue, snipped in next code section
};
Run Code Online (Sandbox Code Playgroud)
我想在上面的接收处理程序中创建返回主题:
var result = channel.QueueDeclare(
queue: ea.BasicProperties.ReplyTo,
durable: false,
exclusive: false,
autoDelete: false,
arguments: null);
Run Code Online (Sandbox Code Playgroud)
或者,我可以将收到的通知存储在数据库中,并通过此列表运行常规计时器,并在每次通过时为每个通道声明一个队列.
在这两种情况下,服务器将在未来的某个时间点使用这个新创建的通道,以向客户端发送查询.
我的问题是:
1)在从客户端接收消息时在服务器上创建回复通道是否更好,或者如果我在外部(在计时器上)执行回复通道,是否存在用于声明已存在的队列的性能问题(可能有数千个端点) )?
2)如果客户端开始错过行为,是否有任何方式可以启动它们(在接收功能中,我可以查找每分钟有多少消息并在满足某些条件时启动)?是否有任何其他过滤器可以在管道接收之前定义,以启动发送过多邮件的客户端?
3)在上面的例子中注意我的消息在每次运行中都会不断出现(相同的旧消息),我该如何清除它们?
我能够从bash发送邮件,但无法更改from文本,它当前显示为"root".
我希望电子邮件客户端在from字段中显示以下文本script on myserver.com (root@myserver.com).
我该怎么办?
emailsubject="$scriptname ($scriptver) log at $startdate"
if [ $errorcount > 0 ]; then
emailsubject="ERRORS($errorcount) - ${emailsubject}"
fi
mail -s "$emailsubject" tobealerted@hotmail.com < $logfile
Run Code Online (Sandbox Code Playgroud)