1

我遇到了问题ReuseScope.Request即使我指定了ReuseScope.Request. 我使用这两个调用来配置容器以获得 MasterConfig:

this.container.RegisterAutoWiredAs<ApiConfigFactory, IConfigFactory>().ReusedWithin(ReuseScope.Container);
this.container.Register(c => c.Resolve<IConfigFactory>().GetMasterConfig(true)).ReusedWithin(ReuseScope.Request);

GetMasterConfig(true) 方法返回一个新的具体 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 Register 上的范围更改为ReuseScope.None,我会按预期加载一个新的 MasterConfig。我错过了什么?我注册 MasterConfig 的方式有问题吗?为什么要ReuseScope.None解决问题?为什么ReuseScope.Request给我同样的例子?

笔记:

4

2 回答 2

0

我也有完全相同的问题,使用 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 并使用调试“生成对象 ID”功能来检查 IOC 容器给我的内容,它们是同一个实例。

呼叫 1:第一个请求

查看由 Visual Studio 创建的 #1 对象 ID

#1 标识

呼叫 2:第二个请求

请参阅#1 对象 ID,这意味着它不应该是同一个实例。它应该是新请求的新实例

相同的对象

并且只是为了证明这些是不同的调用,这里是构造函数运行两次的日志,每个请求一次

在 2 个请求后记录

唯一为我解决这个问题的是Reuse.None的建议修复

但如果我必须这样做,我不妨只使用 AutoFac 适配器(无论如何我更愿意使用)并使用标准 AutoFac INstancePerLifeTimeScope:http ://docs.autofac.org/en/latest/lifetime/instance- scope.html#instance-per-lifetime-scope

有任何想法吗?

于 2017-03-30T14:48:29.510 回答
0

我无法在自主机或 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也可以按预期工作,它不会重复使用实例。

于 2015-08-18T05:08:46.787 回答