脚本
我正在努力遵循ioc模式并使用microsoft di框架,但我遇到了困难,无法决定这是我的思维方式、方法,还是我做错了。
我有一个多租户应用程序,它利用一个实用程序类来处理隔离,并根据租户的独特配置访问其数据。在身份验证期间标识租户,但必须根据请求访问和处理租户数据。这个实用程序类在Startup.cs中的configureservices下注册,构造函数需要两个参数-aTenantDbContext和aTenant

public class TenantUtility{
     public TenantUtility(TenantDbContext context, Tenant tenant){/*...*/}
}

问题
意识到我可能正在突破di框架的限制,我正试图在Startup.cs中构建一个实现工厂。我尝试了两种访问租户id来构建Tenant对象的方法:一种是使用用户声明,另一种是route参数。
services.AddTransient<TenantUtility>((svc)=> {
   var tenantContext = svc.GetService<TenantDbContext>();
   var accessor = svc.GetService<IHttpContextAccessor>();
   var httpContext = accessor.HttpContext;

    //httpContext is NULL...
    //How do I get access to the tenant?
    Common.Tenant t = new Common.Tenant();
    //Set Tenant Identifier in t (once I get it)
    return new StudentDataManager(tenantContext, t);
});

在这两种情况下,当我在startup.cs中设置implementationfactory时,我没有访问用户的权限,也没有访问routedata的权限(或者不知道如何获取它)--我甚至尝试使用IHttpContextAccessor,但HttpContext属性为空。
我是不是走错路了?在将实用程序类传递到控制器之前,我是否应该能够使用di将此级别的详细信息注入实用程序?

最佳答案

您不应该将非DI托管类型传入您希望容器为您提供的服务(在本例中,是您的租户参数)。只请求容器可以提供的服务。如果您需要一个租户,也许可以注入另一个服务,比如itenantAccessor,并能够获得一个租户。
我怀疑您的实现可以在中间件中完成(如果不使用mvc)或作为过滤器(如果使用mvc)。在这两种情况下,都可以使用filter或middleware类中的di注入租户服务。在类的invoke方法中,您将有权访问当前上下文和请求,并且应该能够执行所需的操作。请记住,ConfigureServices在应用程序启动之前运行,因此没有上下文,也没有请求。
如果您想查看一些过滤器的示例,特别是如何将di转换为过滤器,请查看:
https://github.com/ardalis/GettingStartedWithFilters

http://ardalis.com/real-world-aspnet-core-mvc-filters
如果您希望在中间件中执行此操作,则这些可能会有所帮助:
https://github.com/ardalis/NotFoundMiddlewareSample

http://ardalis.com/using-custom-middleware-to-record-and-fix-404s-in-aspnet-core-apps

07-28 01:44
查看更多