相关疑难解决方法(0)

在NServiceBus下管理Windsor中的RavenDb会话

我在MVC 4项目中使用NServiceBus(3.2.2),RavenDB(1.2.2017-Unstable)和Windsor(3.0.0.4001).

我有一个处理3个不同消息的IHandleMessages类,它需要一个IDocumentSession,因此定义了一个属性,例如:

public IDocumentSession DocumentSession { get; set; }
Run Code Online (Sandbox Code Playgroud)

我从NServiceBus的网站上复制了RavenDbUnitOfWork实现

我在我的Windsor容器中注册了IDocumentStore,IDocumentSession和IManageUnitsOfWork,如下所示:

container.Register(
            Component
                .For<IManageUnitsOfWork>()
                .ImplementedBy<RavenUnitOfWork>()
                .LifestyleTransient()
            );
container.Register(
            Component
                .For<IDocumentStore>()
                .UsingFactoryMethod(k => DocumentStoreHolder.DocumentStore)
                .LifestyleSingleton(),
            Component
                .For<IDocumentSession>()
                .UsingFactoryMethod(k => k.Resolve<IDocumentStore>().OpenSession())
                .LifestyleTransient()
            );
Run Code Online (Sandbox Code Playgroud)

NServiceBus配置为使用我的容器:

Configure.With()
         .CastleWindsorBuilder(container);
Run Code Online (Sandbox Code Playgroud)

我遇到的问题是UnitOfWork和消息处理程序接收到DocumentSession的不同实例.这意味着不会保存存储在消息处理程序中的会话中的对象,因为在另一个DocumentSession上调用了SaveChanges().

删除Transient生活方式会导致不同类型的问题,从RavenDb更新对象时会导致并发/冲突,因为(可能)消息处理程序不断获取DocumentSession的相同实例,该实例包含更新对象的缓存版本.

更新:

正如所建议的那样,我已经尝试将Windsor中IDocumentSession的注册更改为Scope生活方式,如下所示:

Component
    .For<IDocumentSession>()
    .UsingFactoryMethod(k => k.Resolve<IDocumentStore>().OpenSession())
    .LifestyleScope()
Run Code Online (Sandbox Code Playgroud)

当容器尝试解析MVC控制器时,这会导致异常,说未找到范围,并询问我是否忘记调用BeginScope().

castle-windsor nservicebus ravendb

5
推荐指数
1
解决办法
806
查看次数

从数据库连接的 RabbitMq 消息中获取租户 ID

我有一个微服务架构,其中包含 ASP.Net Core 应用程序和 RabbitMq 作为微服务之间的事件总线。
我还想支持多租户。
因此,我在 中定义了以下依赖项注入服务,Startup.cs以便根据用户的租户 ID 在每个请求上打开与数据库的连接。

services.AddScoped<IDocumentSession>(ds =>
            {
                var store = ds.GetRequiredService<IDocumentStore>();
                var httpContextAccessor = ds.GetRequiredService<IHttpContextAccessor>();
                var tenant = httpContextAccessor?.HttpContext?.User?.Claims.FirstOrDefault(c => c.Type == "tid")?.Value;
                return tenant != null ? store.OpenSession(tenant) : store.OpenSession();
            });
Run Code Online (Sandbox Code Playgroud)

问题是当服务处理事件总线消息(如 UserUpdatedEvent)时。
在这种情况下,当它尝试打开 Db 连接时,它显然没有来自 http 上下文的用户信息。

在注入作用域服务并使用 RabbitMq 处理事件时,如何发送/访问相应用户的租户 ID?

或者改写我的问题:执行依赖项注入代码时,有什么方法可以访问 RabbitMQ 消息(例如其标头)?

events dependency-injection rabbitmq multi-tenant asp.net-core

1
推荐指数
1
解决办法
1736
查看次数