1

我们有实现IMessageService.RegisterHandler<T>(Func<IMessage<T>, object>)的逻辑。在消息队列的执行块中,我们使用Funq.Container自动连线服务。服务的属性是依赖注入的,但似乎是在线程之间共享的。属性类定义为:ServiceStack:IMessageService中的依赖注入对象的生命周期

_Container.RegisterAutoWired<DbConnectionManager>().ReusedWithin(Funq.ReuseScope.Request); 

大多数情况下,DbConnectionManager属性是作为新对象创建的。但是,在一些非常繁忙的时间里,我们注意到DbConnectionManager在线程间重用并导致问题。

我的问题是:什么是依赖注入的对象,这是由两个Web请求和消息队列使用的生命周期设置?关于我们遇到的这个特殊问题的任何见解?太感谢了!

回答

0

请勿将请求范围用于MQ请求。如果相关性是线程使用默认的单登记:

container.RegisterAutoWired<DbConnectionManager>(); 

否则,如果它不是线程安全的,其注册为一过性的依赖:

container.RegisterAutoWired<DbConnectionManager>().ReusedWithin(ReuseScope.None); 
+0

感谢@mythz。这证实了我对问题原因的怀疑。但是,在这种DbConnectionManager也被很多普通服务使用的情况下(我们需要为每个请求保留一个实例),我无法想到其他方式,而是创建一个单独的DbConnectionManagerForMQ类来使用ReuseScope.None。那是建议的吗? –

+0

@JamesChen使用请求范围几乎总是一个坏主意,要么依赖是线程安全的,在这种情况下使用单例,或者它不是在这种情况下使用瞬态。当您需要单例依赖API背后的性能实现池时,并在使用后立即将实例释放回池中,从而最大限度地减少资源争用。如果您需要在整个请求管道中共享对象,请使用'IRequest.Items'字典。我想不出使用请求范围的一个好理由。 – mythz

+0

我们有一些不同的逻辑,它们在自己的代码块中执行数据库操作。当我们将它们组合在一个层次结构中时,我们希望有一个DbConnection和Transaction,因此我们将此DbConnectionManager作为DbConnection封装器引入,以避免嵌套事务。瞬态类型不能以这种方式工作。我也在考虑使用ReuseScope.Container并在Web请求和MQ中管理子容器。你认为这是一个有效的方法? –