我正在使用ServiceStack的funq,我的AppHost文件中有以下代码。由于应用程序池大小达到最大限制,API命中超时过期错误。
var dbFactory = new OrmLiteConnectionFactory(string.Empty, SqlServerDialect.Provider);
...
// Loop to get multiple different country connection string
foreach (string server in countryCodeList)
{
dbFactory.RegisterConnection(server, connectionString, SqlServerDialect.Provider);
}
this.RequestFilters.Add((httpReq, httpRes, requestDto) =>
{
requestInfo = requestDto.Dump();
...
container.Register<IReferenceRepository>(c => new ReferenceRepository(dbFactory, baseModel.db_country_code));
container.Register<ICompanyRepository>(c => new CompanyRepository(dbFactory, baseModel.db_country_code));
...
});
我在我的Repository基类中实现了IDisposable。但它似乎并没有在每个请求结束时处理连接。在perfmon.exe中可以看到NumberOfPooledConnections在不丢弃的情况下为每个请求保持增加。
Repository bass class中的代码:
public class Repository : IDisposable
{
protected IDbConnectionFactory dbFactory { get; set; }
public string CountryCode { get; set; }
private IDbConnection db;
public Repository(IDbConnectionFactory dbConnectionFactory, string countryCode)
{
this.dbFactory = dbConnectionFactory;
this.CountryCode = countryCode;
}
protected virtual IDbConnection Db(string connectionKey)
{
return db ?? (db = dbFactory.OpenDbConnection(connectionKey));
}
public virtual void Dispose()
{
if (db != null)
db.Dispose();
}
}
只是想知道是否将 ReusedWithin(ReuseScope.Request)添加到container.Register部分会有帮助吗?
如果我以正确的方式做事,有人可以指导我吗?提前致谢。
已编辑:API请求将从一个服务调用另一个服务,并从不同的存储库获取数据。
答案 0 :(得分:1)
ServiceStack中的所有依赖项都应该在AppHost.Configure()
中注册,它在StartUp上运行一次,之后应该被认为是不可变的。
你不应该在RequestFilter中对注册依赖关系(在每个请求上运行)。
OrmLiteConnectionFactory
(与ServiceStack中的所有工厂一样)被设计为注册为单例,这也是Funq中的默认生命周期,即:
container.Register<IDbConnectionFactory>(
c => new OrmLiteConnectionFactory(connString, SqlServerDialect.Provider));
然后,您可以从IOC解析它以注册您的命名连接,例如:
var factory=(OrmLiteConnectionFactory)container.Resolve<IDbConnectionFactory>();
foreach (string server in countryCodeList)
{
factory.RegisterConnection(server, connString, SqlServerDialect.Provider);
}
您的存储库之类的所有其他依赖项也应在AppHost.Configure()
中注册。如果它实现IDisposable
且ReuseScope为None
或Request
,则会在请求结束时将其处理。
由于需要在StartUp上注册依赖项,因此它无法访问请求数据。如果需要,那么需要在运行时传递它。
您可以通过将样板添加到基本服务类来减少样板,例如:
public abstract class AppServiceBase : Service
{
public IDbConnectionFactory DbFactory
{
get { return TryResolve<IDbConnectionFactory>(); }
}
ReferenceRepository refRepo;
public ReferenceRepository ReferenceRepo
{
get
{
if (refRepo == null)
refRepo = new ReferenceRepository(
DbFactory.OpenDbConnection(Request.Param("c_code")));
return refRepo;
}
}
public override Dispose()
{
base.Dispose();
if (refRepo != null)
refRepo.Dispose();
}
}
然后您的服务可以像普通依赖一样访问,即:
public class MyService : AppServiceBase
{
public object Get(Request request)
{
var foo = ReferenceRepo.GetById(request.Id);
}
}