ServiceStack Funq ReuseScope.Request 注入相同的对象而不是新实例
ServiceStack Funq ReuseScope.Request injects same object instead of a new instance
我遇到了 ReuseScope.Request
的问题。即使我指定 ReuseScope.Request
,我也会在每个请求中注入 same 实例。我使用这两个调用配置容器以获取 MasterConfig:
this.container.RegisterAutoWiredAs<ApiConfigFactory, IConfigFactory>().ReusedWithin(ReuseScope.Container);
this.container.Register(c => c.Resolve<IConfigFactory>().GetMasterConfig(true)).ReusedWithin(ReuseScope.Request);
GetMasterConfig(true) 方法returns 一个新的具体 MasterConfig。但是,当我尝试在服务中使用 MasterConfig 时,我在每次请求时都会得到相同的实例。
public class MyService
{
private readonly MasterConfig masterConfig;
public SaleService(MasterConfig masterConfig)
{
this.masterConfig = masterConfig;
}
public object Post(MyRequest request)
{
// **masterConfig is the same instance here on every request**
}
}
如果我将 MasterConfig 寄存器的范围更改为 ReuseScope.None
,我将按预期加载新的 MasterConfig。我错过了什么?我注册MasterConfig的方式有问题吗?为什么 ReuseScope.None
解决了这个问题?为什么 ReuseScope.Request
给我相同的实例?
注:
我无法在自托管或 ASP.NET 托管中重现此内容。
这适用于最新版本的 ServiceStack:
//AppHost
public class RequestScopeAppHost : AppSelfHostBase
{
public RequestScopeAppHost()
: base(typeof(RequestScopeAppHost).Name, typeof(RequestScopeService).Assembly) {}
private static int counter = 0;
public override void Configure(Container container)
{
container.Register(c => new MasterConfig {
Id = Interlocked.Increment(ref counter)
}).ReusedWithin(ReuseScope.Request);
}
}
服务:
public class MasterConfig
{
public int Id { get; set; }
}
public class GetMasterConfig : IReturn<MasterConfig> { }
public class RequestScopeService : Service
{
private readonly MasterConfig config;
public RequestScopeService(MasterConfig config)
{
this.config = config;
}
public object Any(GetMasterConfig request)
{
return config;
}
}
测试:
[TestFixture]
public class RequestScopeIssue
{
private readonly ServiceStackHost appHost;
public RequestScopeIssue()
{
appHost = new RequestScopeAppHost()
.Init()
.Start(Config.AbsoluteBaseUri);
}
[TestFixtureTearDown]
public void TestFixtureTearDown()
{
appHost.Dispose();
}
[Test]
public void Can_get_RequestScope_dependency()
{
var client = new JsonServiceClient(Config.AbsoluteBaseUri);
Assert.That(client.Get(new GetMasterConfig()).Id, Is.EqualTo(1));
Assert.That(client.Get(new GetMasterConfig()).Id, Is.EqualTo(2));
Assert.That(client.Get(new GetMasterConfig()).Id, Is.EqualTo(3));
}
}
在您的描述中 ReuseScope.None
也按预期工作,它不会重复使用实例。
我也有完全相同的问题,使用 ServiceStack 版本 4.5.6
这是我的注册码
container.RegisterAutoWiredAs<EventConditionalLoadingRepository, IEventConditionalLoadingRepository>()
.ReusedWithin(ReuseScope.Request);
container.RegisterAutoWiredAs<MetaRiskRepository, IMetaRiskRepository>()
.ReusedWithin(ReuseScope.Request);
container.RegisterAutoWiredAs<RiskStoreConnectivityService, IRiskStoreConnectivityService>()
.ReusedWithin(ReuseScope.Request);
container.Register<IUnitOfWork>(c =>
{
return new UnitOfWork();
}).ReusedWithin(ReuseScope.Request);
container.Register(c => (IUnitOfWorkEnlistable)c.Resolve<IUnitOfWork>())
.ReusedWithin(ReuseScope.Request);
这是我的服务,需要这些依赖项
public AnalysisServiceStackService(
IEventConditionalLoadingRepository eventConditionalLoadingRepository,
IMetaRiskRepository metaRiskRepository,
IUnitOfWork unitOfWork)
{
_eventConditionalLoadingRepository = eventConditionalLoadingRepository;
_metaRiskRepository = metaRiskRepository;
_unitOfWork = unitOfWork;
_log.Information("AnalysisServiceStackService constructed");
}
你可以看到我在那里有一个日志语句,当我通过邮递员为顺序请求打开这个服务时,我记录了这种事情
2017-03-30 15:34:10 [Information] AnalysisServiceStackService constructed
2017-03-30 15:34:11 [Information] AnalysisServiceStackService constructed
2017-03-30 15:34:12 [Information] AnalysisServiceStackService constructed
2017-03-30 15:34:13 [Information] AnalysisServiceStackService constructed
2017-03-30 15:34:14 [Information] AnalysisServiceStackService constructed
2017-03-30 15:34:15 [Information] AnalysisServiceStackService constructed
2017-03-30 15:34:16 [Information] AnalysisServiceStackService constructed
2017-03-30 15:34:17 [Information] AnalysisServiceStackService constructed
所以我知道服务本身应该尝试解析它需要的 IOC 组件的新 PerRequest 实例。
如果我然后使用 Visual studio 并使用调试 "Make Object ID" 功能来检查 IOC 容器给我的是同一个实例。
调用 1:第一个请求
查看 Visual Studio
创建的 #1 对象 ID
调用 2:第二个请求
查看 #1 对象 ID,这意味着它应该是同一个实例。它应该是新请求的新实例
为了证明这些是不同的调用,这里是构造函数的日志 运行 两次,每个请求一次
唯一为我解决这个问题的是 Reuse.None
的建议修复
但如果我必须这样做,我还不如使用 AutoFac 适配器(无论如何我更愿意使用它)并使用标准的 AutoFac INstancePerLifeTimeScope:http://docs.autofac.org/en/latest/lifetime/instance-scope.html#instance-per-lifetime-scope
有什么想法吗?
我遇到了 ReuseScope.Request
的问题。即使我指定 ReuseScope.Request
,我也会在每个请求中注入 same 实例。我使用这两个调用配置容器以获取 MasterConfig:
this.container.RegisterAutoWiredAs<ApiConfigFactory, IConfigFactory>().ReusedWithin(ReuseScope.Container);
this.container.Register(c => c.Resolve<IConfigFactory>().GetMasterConfig(true)).ReusedWithin(ReuseScope.Request);
GetMasterConfig(true) 方法returns 一个新的具体 MasterConfig。但是,当我尝试在服务中使用 MasterConfig 时,我在每次请求时都会得到相同的实例。
public class MyService
{
private readonly MasterConfig masterConfig;
public SaleService(MasterConfig masterConfig)
{
this.masterConfig = masterConfig;
}
public object Post(MyRequest request)
{
// **masterConfig is the same instance here on every request**
}
}
如果我将 MasterConfig 寄存器的范围更改为 ReuseScope.None
,我将按预期加载新的 MasterConfig。我错过了什么?我注册MasterConfig的方式有问题吗?为什么 ReuseScope.None
解决了这个问题?为什么 ReuseScope.Request
给我相同的实例?
注:
我无法在自托管或 ASP.NET 托管中重现此内容。
这适用于最新版本的 ServiceStack:
//AppHost
public class RequestScopeAppHost : AppSelfHostBase
{
public RequestScopeAppHost()
: base(typeof(RequestScopeAppHost).Name, typeof(RequestScopeService).Assembly) {}
private static int counter = 0;
public override void Configure(Container container)
{
container.Register(c => new MasterConfig {
Id = Interlocked.Increment(ref counter)
}).ReusedWithin(ReuseScope.Request);
}
}
服务:
public class MasterConfig
{
public int Id { get; set; }
}
public class GetMasterConfig : IReturn<MasterConfig> { }
public class RequestScopeService : Service
{
private readonly MasterConfig config;
public RequestScopeService(MasterConfig config)
{
this.config = config;
}
public object Any(GetMasterConfig request)
{
return config;
}
}
测试:
[TestFixture]
public class RequestScopeIssue
{
private readonly ServiceStackHost appHost;
public RequestScopeIssue()
{
appHost = new RequestScopeAppHost()
.Init()
.Start(Config.AbsoluteBaseUri);
}
[TestFixtureTearDown]
public void TestFixtureTearDown()
{
appHost.Dispose();
}
[Test]
public void Can_get_RequestScope_dependency()
{
var client = new JsonServiceClient(Config.AbsoluteBaseUri);
Assert.That(client.Get(new GetMasterConfig()).Id, Is.EqualTo(1));
Assert.That(client.Get(new GetMasterConfig()).Id, Is.EqualTo(2));
Assert.That(client.Get(new GetMasterConfig()).Id, Is.EqualTo(3));
}
}
在您的描述中 ReuseScope.None
也按预期工作,它不会重复使用实例。
我也有完全相同的问题,使用 ServiceStack 版本 4.5.6
这是我的注册码
container.RegisterAutoWiredAs<EventConditionalLoadingRepository, IEventConditionalLoadingRepository>()
.ReusedWithin(ReuseScope.Request);
container.RegisterAutoWiredAs<MetaRiskRepository, IMetaRiskRepository>()
.ReusedWithin(ReuseScope.Request);
container.RegisterAutoWiredAs<RiskStoreConnectivityService, IRiskStoreConnectivityService>()
.ReusedWithin(ReuseScope.Request);
container.Register<IUnitOfWork>(c =>
{
return new UnitOfWork();
}).ReusedWithin(ReuseScope.Request);
container.Register(c => (IUnitOfWorkEnlistable)c.Resolve<IUnitOfWork>())
.ReusedWithin(ReuseScope.Request);
这是我的服务,需要这些依赖项
public AnalysisServiceStackService(
IEventConditionalLoadingRepository eventConditionalLoadingRepository,
IMetaRiskRepository metaRiskRepository,
IUnitOfWork unitOfWork)
{
_eventConditionalLoadingRepository = eventConditionalLoadingRepository;
_metaRiskRepository = metaRiskRepository;
_unitOfWork = unitOfWork;
_log.Information("AnalysisServiceStackService constructed");
}
你可以看到我在那里有一个日志语句,当我通过邮递员为顺序请求打开这个服务时,我记录了这种事情
2017-03-30 15:34:10 [Information] AnalysisServiceStackService constructed
2017-03-30 15:34:11 [Information] AnalysisServiceStackService constructed
2017-03-30 15:34:12 [Information] AnalysisServiceStackService constructed
2017-03-30 15:34:13 [Information] AnalysisServiceStackService constructed
2017-03-30 15:34:14 [Information] AnalysisServiceStackService constructed
2017-03-30 15:34:15 [Information] AnalysisServiceStackService constructed
2017-03-30 15:34:16 [Information] AnalysisServiceStackService constructed
2017-03-30 15:34:17 [Information] AnalysisServiceStackService constructed
所以我知道服务本身应该尝试解析它需要的 IOC 组件的新 PerRequest 实例。
如果我然后使用 Visual studio 并使用调试 "Make Object ID" 功能来检查 IOC 容器给我的是同一个实例。
调用 1:第一个请求
查看 Visual Studio
创建的 #1 对象 ID调用 2:第二个请求
查看 #1 对象 ID,这意味着它应该是同一个实例。它应该是新请求的新实例
为了证明这些是不同的调用,这里是构造函数的日志 运行 两次,每个请求一次
唯一为我解决这个问题的是 Reuse.None
的建议修复但如果我必须这样做,我还不如使用 AutoFac 适配器(无论如何我更愿意使用它)并使用标准的 AutoFac INstancePerLifeTimeScope:http://docs.autofac.org/en/latest/lifetime/instance-scope.html#instance-per-lifetime-scope
有什么想法吗?