我的情况是vnext的DI容器的经典功能不足以为我提供正确的功能。我们假设我有一个DataService从数据库中获取数据,如下所示:
public class DataService : IDataService, IDisposable {
public List<MyObject> GetMyObjects()
{
// do something to fetch the data...
return myObjects;
}
}
然后我可以在Startup.cs
:
public void ConfigureServices(IServiceCollection services)
{
services.AddScoped(typeof(IDataService), typeof(DataService));
}
这确保了服务的正确生命周期(每个请求范围一个),但是,当发出不同的请求时,我需要服务访问不同的数据库。为简单起见,我们假设以下情况适用:
DataService
将访问当前登录的用户,该用户包含一个名为Database
的声明,其中包含要使用的数据库的信息。DataService
。为了让第二步工作,我为DataService创建了一个构造函数,如下所示:
public DataService(IHttpContextAccessor accessor)
{
// get the information from HttpContext
var currentUser = accessor.HttpContext.User;
var databaseClaim = currentUser.Claims.SingleOrDefault(c => c.Type.Equals("Database"));
if (databaseClaim != null)
{
var databaseId = databaseClaim.Value;
// and use this information to create the correct database connection
this.database = new Database(databaseId);
}
}
通过使用当前登录的用户及其声明,我可以确保我自己的身份验证中间件负责提供必要的信息,以防止攻击者试图访问错误的数据库。
当然,需要添加IDisposable
实现来清理任何数据库连接(并使用范围生命周期正确调用)。
然后我可以将DataService
注入像这样的控制器
public MyController : Controller
{
private IDataService dataService;
public MyController(IDataService dataService)
{
this.dataService = dataService;
}
}
到目前为止一切正常。 我现在的问题是:
DataService
的构造函数之外,还有其他方法可以创建实例吗?也许访问IServiceCollection
提供的对象在除了仅运行一次的配置阶段之外的其他地方?也许使用我自己的OWIN中间件?DataService
为其他请求而结束,因此最终会发出错误的数据?答案 0 :(得分:1)
你所拥有的一切都很好。
除了使用DataService的构造函数之外,还有另一种方法来创建实例吗?也许访问IServiceCollection提供的对象除了在仅运行一次的配置阶段之外的其他地方?也许使用我自己的OWIN中间件?
不是真的。您可以使用委托注册,但这是同样的问题。
这种方法真的安全吗?
是
同时发出的两个请求是否会意外地以另一个请求的DataServiceintended结束,因此最终会发出错误的数据?
不。 IHttpContextAcessor使用AsyncLocal(http://blog.stephencleary.com/2013/04/implicit-async-context-asynclocal.html)来提供对“当前”http上下文的访问。