InvalidOperationException:无法解析类型

时间:2016-12-17 07:47:11

标签: c# dependency-injection asp.net-core asp.net-core-mvc saaskit

我正在使用saaskit多租户项目进行多租户申请。

我能够创建租户上下文并能够访问所有控制器。

但是,有时它会给我以下错误

  

发生了未处理的异常:无法解析服务   尝试激活时输入'LMS.Model.AppTenant'   'LMS.Controllers.OrganizationController'。

任何控制器和执行的任何操作方法都会随机发生此错误。错误的性质并非特定于任何控制器/操作方法。

我可以看到我的代码成功进入了TenantResolver,这实际上确实返回了一个租户但是当它将DI注入我的控制器时它会引发错误列出

发生此错误后,我的应用程序完全停止并显示白屏。

此问题发生在生产服务器上,而不是在localhost上。

对此有任何帮助!

租户注入所有控制器,如此

public class HomeController
    {
        public HomeController(TenantContext<AppTenant> tenantContext)
        {

        }
    }

及以下是tenantContext可注入的扩展类

public static class MultitenancyServiceCollectionExtensions
    {
        public static IServiceCollection AddMultitenancy<TTenant, TResolver>(this IServiceCollection services) 
            where TResolver : class, ITenantResolver<TTenant>
            where TTenant : class
        {
            Ensure.Argument.NotNull(services, nameof(services));

            services.AddScoped<ITenantResolver<TTenant>, TResolver>();

            // Make Tenant and TenantContext injectable
            services.AddScoped(prov => 
                prov.GetService<IHttpContextAccessor>()?.HttpContext?.GetTenant<TTenant>());

            services.AddScoped(prov =>
                prov.GetService<IHttpContextAccessor>()?.HttpContext?.GetTenantContext<TTenant>());

            // Ensure caching is available for caching resolvers
            services.AddMemoryCache();

            return services;
        }
    }

对此有任何帮助表示赞赏!

1 个答案:

答案 0 :(得分:1)

你不能/不应该这样做。问题在于您的注册:

// Make Tenant and TenantContext injectable
services.AddScoped(prov => 
    prov.GetService<IHttpContextAccessor>()?.HttpContext?.GetTenant<TTenant>());

services.AddScoped(prov =>
    prov.GetService<IHttpContextAccessor>()?.HttpContext?.GetTenantContext<TTenant>());

他们都可以null!注册依赖项时,必须从不null

在这种情况下,您必须确保始终返回Tenant,如果没有租户信息,则返回通用或未初始化的Tenant实例。您的TenantContext<AppTenant>也是如此。它必须始终为非空,但租户可能不必包含有效的租户信息,即您可以在其上设置IsValid属性以检查其是否为有效租户。

当有人错误输入包含租户的网址部分或访问没有租户标题的网页时(或者您正在处理租户),您可能拥有无效租户。

您有时会遇到此问题的原因有时并不是因为服务是按请求(作用域),因此对于每个请求,它将尝试再次调用工厂方法,并且每次都可以导致null。 / p>