我处于vnext的DI容器的经典功能不足以为我提供正确功能的情况。假设我有一个DataService可以从这样的数据库中获取数据:

public class DataService : IDataService, IDisposable {
  public List<MyObject> GetMyObjects()
  {
    // do something to fetch the data...
    return myObjects;
  }
}


然后,我可以在Startup.cs的配置阶段在DI容器中注册此服务:

public void ConfigureServices(IServiceCollection services)
{
  services.AddScoped(typeof(IDataService), typeof(DataService));
}


这样可以确保服务的正确生命周期(每个请求范围一个),但是,当发出不同的请求时,我需要该服务访问不同的数据库。为了简单起见,假设以下情况适用:


当向我的Web API发出请求时,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意外结束并因此给出错误的数据?

最佳答案

你所拥有的一切都很好。


  除了使用DataService的构造函数之外,还有其他方法可以创建实例吗?也许访问IServiceCollection提供的对象的位置不同于仅运行一次的配置阶段,而是在其他位置?也许使用我自己的OWIN中间件?


并不是的。您可以使用委托注册,但这是相同的问题。


  这种方法真的安全吗?





  同时发出的两个请求是否会意外地与另一个请求的DataServiceintended一起,从而最终给出错误的数据?


不。 IHttpContextAcessor使用AsyncLocal(http://blog.stephencleary.com/2013/04/implicit-async-context-asynclocal.html)提供对“当前” http上下文的访问。

关于c# - 如何在ASP.NET 5中动态创建和注入(inject)服务?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/33760578/

10-10 12:27