您好我正在使用Simple Injector DI库并且已经关注了一些关于围绕命令模式设计的架构模型的非常有趣的材料:
容器将管理生命周期UnitOfWork,我使用命令来执行数据库的特定功能.
我的问题是,如果我有一个命令,例如一个AddNewCustomerCommand,它反过来执行另一个服务的另一个调用(即发送文本消息),从设计的角度来看这是可接受的还是应该在更高的层次上完成,如果是的话最好这样做?
示例代码如下:
public class AddNewBusinessUnitHandler
: ICommandHandler<AddBusinessUnitCommand>
{
private IUnitOfWork uow;
private ICommandHandler<OtherServiceCommand> otherHandler;
AddNewBusinessUnitHandler(IUnitOfWork uow,
ICommandHandler<OtherServiceCommand> otherHandler)
{
this.uow = uow;
this.otherHandler = otherHandler;
}
public void Handle(AddBusinessUnitCommand command)
{
var businessUnit = new BusinessUnit()
{
Name = command.BusinessUnitName,
Address = command.BusinessUnitAddress
};
var otherCommand = new OtherServiceCommand()
{
welcomePostTo = command.BusinessUnitName
};
uow.BusinessUnitRepository.Add(businessUnit);
this.otherHandler.Handle(otherCommand);
}
}
Run Code Online (Sandbox Code Playgroud) 我有多个服务,每个服务都UnitOfWork使用Simple Injector IoC容器注入构造函数.
目前我可以看到每个UnitOfWork实例都是一个单独的对象,这很糟糕,因为我使用的是Entity Framework,并且需要在所有工作单元中使用相同的上下文引用.
如何确保UnitOfWork每个解析请求将相同的实例注入到所有服务中?UnitOfWor命令完成后,我将由外部命令处理程序装饰器保存.
请注意,这是一个公共库,将用于MVC和Windows Forms,如果可能的话,为两个平台提供通用解决方案会很不错.
代码如下:
// snippet of code that registers types
void RegisterTypes()
{
// register general unit of work class for use by majority of service layers
container.Register<IUnitOfWork, UnitOfWork>();
// provide a factory for singleton classes to create their own units of work
// at will
container.RegisterSingle<IUnitOfWorkFactory, UnitOfWorkFactory>();
// register logger
container.RegisterSingle<ILogger, NLogForUnitOfWork>();
// register all generic command handlers
container.RegisterManyForOpenGeneric(typeof(ICommandHandler<>),
AppDomain.CurrentDomain.GetAssemblies());
container.RegisterDecorator(typeof(ICommandHandler<>),
typeof(TransactionCommandHandlerDecorator<>));
// register …Run Code Online (Sandbox Code Playgroud) .net c# dependency-injection entity-framework-4 simple-injector
我正在使用Simple Injector来管理我注入的依赖项的生命周期(在这种情况下UnitOfWork),我很高兴有一个单独的装饰器而不是我的服务或命令处理程序,在编写业务逻辑时保存和处理使代码更容易图层(我遵循本博文中概述的架构).
通过在构造根容器的构造过程中使用Simple Injector MVC NuGet包和以下代码,上面的工作完美(并且非常容易),如果图中存在多个依赖项,则相同实例将全部注入 - 完美的实体框架模型上下文.
private static void InitializeContainer(Container container)
{
container.RegisterPerWebRequest<IUnitOfWork, UnitOfWork>();
// register all other interfaces with:
// container.Register<Interface, Implementation>();
}
Run Code Online (Sandbox Code Playgroud)
我现在需要运行一些后台线程并从Simple Injector 文档中了解可以代理命令的线程,如下所示:
public sealed class TransactionCommandHandlerDecorator<TCommand>
: ICommandHandler<TCommand>
{
private readonly ICommandHandler<TCommand> handlerToCall;
private readonly IUnitOfWork unitOfWork;
public TransactionCommandHandlerDecorator(
IUnitOfWork unitOfWork,
ICommandHandler<TCommand> decorated)
{
this.handlerToCall = decorated;
this.unitOfWork = unitOfWork;
}
public void Handle(TCommand command)
{
this.handlerToCall.Handle(command);
unitOfWork.Save();
}
}
Run Code Online (Sandbox Code Playgroud)
ThreadedCommandHandlerProxy:
public class ThreadedCommandHandlerProxy<TCommand>
: ICommandHandler<TCommand> …Run Code Online (Sandbox Code Playgroud) 我已经看过很多关于EventStores的内容,但所有文章都与CQRS相关.
我们希望使用EventStores来集成有界上下文,但希望坚持使用传统的ORM来读/写聚合,以避免命令/查询和单独的读取模型,在我们的例子中会增加太多的复杂性.
因为它是如此流行地讨论这两个概念而导致人们认为它们意味着共同生活 - 与没有CQRS的EventStore'lite'相比,是否存在陷阱,与实现聚合/ CQRS /读取模型的EventStore相比?
我在最新的 Windows 版本 Windows 10 2004 上使用 Linux 容器并启用 WSL 2 和 Docker Desktop 2.3.0.3 (45519)。
我右键单击 docker-compose 文件,然后选择Set as Startup Project.
然后我按 F5 进行调试。
我可以看到正在运行的图像,docker ps但是没有命中断点。
我无法查看日志(在 Visual Studio Containers 窗口中),因为它说:
It was not possible to find any compatible framework version
The framework 'Microsoft.AspNetCore.App', version '3.1.0' was not found.
- No frameworks were found.
You can resolve the problem by installing the specified framework and/or SDK.
The specified framework can be found at:
- https://aka.ms/dotnet-core-applaunch?framework=Microsoft.AspNetCore.App&framework_version=3.1.0&arch=x64&rid=debian.10-x64 …Run Code Online (Sandbox Code Playgroud) 我正在使用Microsoft Unit Test并具有以下内容:
public class AccountCommandHandlers :
Handler<CreateAccountCommand>,
Handler<CloseAccountCommand>
{
public bool CreateAccountCommandWasCalled = false;
public bool CloseAccountCommandWasCalled = false;
public void Handle(CreateAccountCommand command)
{
CreateAccountCommandWasCalled = true;
}
public void Handle(CloseAccountCommand command)
{
CloseAccountCommandWasCalled = true;
}
}
[TestMethod]
public void CanRaiseInternalHandlers()
{
var iocContainer = SimpleInjectorWiringForMembus.Instance;
iocContainer.Bootstrap(
AppDomain.CurrentDomain.GetAssemblies());
var membus = MembusWiring.Instance;
membus.Bootstrap();
membus.Bus.Publish(new CreateAccountCommand() { Id = 100 });
membus.Bus.Publish(new CloseAccountCommand() { Id = 100 });
}
Run Code Online (Sandbox Code Playgroud)
我正在使用IoC容器(Simple Injector)来处理对象的生命周期范围.Membus将命令连接到命令处理程序,并通过IoC容器解析.
上面的代码运行并运行,命令处理程序将其局部变量设置为true.
但是,由于Simple Injector处理生命周期范围,我无法向Simple Injector请求一个AccountCommandHandler对象,因为它会返回一个CreateAccountCommandWasCalled设置为false …
我有一个基类:
public abstract class DomainEventSubscriber<T> where T : DomainEvent
{
public abstract void HandleEvent(T domainEvent);
public Type SubscribedToEventType() { return typeof(T); }
}
Run Code Online (Sandbox Code Playgroud)
还有一个存储DomainEventSubscriber引用的类:
public class DomainEventPublisher
{
private List<DomainEventSubscriber<DomainEvent>> subscribers;
public void Subscribe<T>(DomainEventSubscriber<T> subscriber)
where T : DomainEvent
{
DomainEventSubscriber<DomainEvent> eventSubscriber;
eventSubscriber = (DomainEventSubscriber<DomainEvent>)subscriber;
if (!this.Publishing)
{
this.subscribers.Add(eventSubscriber);
}
}
}
Run Code Online (Sandbox Code Playgroud)
即使Subscribe方法类型受到限制,我也无法转换DomainEventSubscriber<T> subscriber where T : DomainEvent为DomainEventSubscriber<DomainEvent>:
eventSubscriber = (DomainEventSubscriber<DomainEvent>)subscriber;
Run Code Online (Sandbox Code Playgroud)
我将如何进行这种转换,或者我是否为一个令人讨厌的代码味道做好准备?
据我所知,MemoryPool和ArrayPool之间有什么区别,它们都做同样的事情(出租缓冲区以减少垃圾收集压力)。
是否有一个池应该在读取调用中首选使用NetworkStream或WebSocket?
我有一个默认的通用主机构建器,如下所示:
public static IHostBuilder CreateDefaultBuilder(string[] args)
{
var builder = Host.CreateDefaultBuilder(args);
builder
.ConfigureLogging((hostingContext, logging) =>
{
logging.ClearProviders();
logging.AddConsole();
if (hostingContext.HostingEnvironment.IsDevelopment() == true)
logging.AddDebug();
})
.ConfigureHostConfiguration(configurationBuilder =>
{
configurationBuilder.AddCommandLine(args);
})
.ConfigureAppConfiguration((hostingContext, configApp) =>
{
var env = hostingContext.HostingEnvironment;
Console.WriteLine(env.EnvironmentName);
})
.UseConsoleLifetime();
return builder;
}
public static async Task Main(string[] args)
{
var host = CreateDefaultBuilder(args)
.ConfigureServices((hostContext, services) =>
{
services.Configure<HostOptions>(option =>
{
option.ShutdownTimeout = System.TimeSpan.FromSeconds(20);
});
services.AddLogging();
services.AddSimpleInjector(container, options =>
{
// Hooks hosted services into the Generic Host pipeline while …Run Code Online (Sandbox Code Playgroud) 我有一个正在运行的石英作业并BackgroundService由于某种原因终止了我的scheduler.Shutdown(true).
即使在循环和中断作业时,程序也会在线程退出之前关闭。
除了我下面的代码,我是否会考虑编写自定义 IScheduler 以确保运行作业在关机时停止?
这是我的IJob执行方法:
public async Task Execute(IJobExecutionContext context)
{
var cancellationToken = context.CancellationToken;
while (cancellationToken.IsCancellationRequested == false)
{
// Extension method so we catch TaskCancelled exceptions.
await TaskDelay.Wait(1000, cancellationToken);
Console.WriteLine("keep rollin, rollin, rollin...");
}
Console.WriteLine("Cleaning up.");
await Task.Delay(1000);
Console.WriteLine("Really going now.");
}
Run Code Online (Sandbox Code Playgroud)
这是我的关机循环(直接调用关机不会中断任何正在运行的作业):
internal class QuartzHostedService : IHostedService
{
// These are set by snipped constructor.
private readonly IJobSettings jobSettings;
private readonly ILogger logger;
private readonly IScheduler scheduler;
private async Task …Run Code Online (Sandbox Code Playgroud) c# ×9
.net ×5
.net-core ×3
docker ×2
architecture ×1
generics ×1
membus ×1
neventstore ×1
quartz.net ×1
unit-of-work ×1
unit-testing ×1