我有一个ASP.NET MVC,它可以在Application_Start方法中初始化Simple Injector。

该错误在本地正常使用该网站的过程中间歇性出现,并且在Visual Studio中重建该网站时始终消失。在部署时,该错误会立即出现,但是可以通过在服务器上重新启动该应用程序来消除此错误。过了一会儿,它又出现了。

启动代码如下:

public class CmsApplication : System.Web.HttpApplication
{
    private Container _container;
    private IQueryProcessor queryProcessor;

    private static ISiteManager _manager;
    public static ISiteManager SiteManager { get { return _manager; } }

    protected virtual void Application_Start()
    {
        // Mapping using AutoMapper
        CMS.UI.Client.Mapping.MappingConfig.RegisterMappings();

        // Initialize SimpleInjector
        InitializeIoC();

        AutoMapper.Mapper.AssertConfigurationIsValid();

        // Get query processor - this is used for handling database calls.
        queryProcessor = _container.GetInstance<IQueryProcessor>();

        // Get configuration
        IConfiguration configuration = CMS.Configuration.ConfigurationFactory.Get();

        // MVC Stuff
        AreaRegistration.RegisterAllAreas();
        RouteConfig routeConfig = new RouteConfig(queryProcessor);
        routeConfig.RegisterRoutes(RouteTable.Routes);

        FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

        // Regular MVC startup
        AreaRegistration.RegisterAllAreas();

        // Global SiteManager property. THIS COULD BE CAUSING THE ISSUE!
        _manager = _container.GetInstance<ISiteManager>();

    }

    /// <summary>
    /// Method to initialize the IoC Container
    /// </summary>
    protected void InitializeIoC()
    {
        // Initialize DI container
        _container = new Container();

        // Allows container to inject into filter constructors
        _container.RegisterMvcIntegratedFilterProvider();

        // Mapping
        _container.Register<AutoMapper.IMappingEngine>(() => (AutoMapper.IMappingEngine)AutoMapper.Mapper.Engine, Lifestyle.Singleton);
        _container.Register<IMapProcessor, MapProcessor>(); // Map Processor

        // Configuration
        _container.Register<IConfiguration>(() => (CMS.Configuration.Configuration)System.Configuration.ConfigurationManager.GetSection("pipeline"), Lifestyle.Singleton);

        // Site Manager
        _container.Register<ISiteManager, SiteManager>(Lifestyle.Singleton);

        // Context and UnitOfWork Factories
        _container.RegisterPerWebRequest<IContext>(() => new CrmContext("Name=CrmContext"));

        // Context and UnitOfWork
        _container.RegisterPerWebRequest<Pipeline.Core.Data.UnitOfWork.IUnitOfWork, Crm.UnitOfWork.EFUnitOfWork>();

        // Repositories
        _container.Register<ISiteRepository, SiteRepository>();
        _container.Register<IFolderRepository, FolderRepository>();

        // Sitemap
        _container.Register<ISitemapGenerator, SitemapGenerator>();

        // Robots
        _container.Register<IRobotsGenerator, RobotsGenerator>();

        // Command Handlers
        _container.RegisterOpenGeneric(
            typeof(IBatchCommandHandler<>), typeof(BatchCommandHandler<>));

        _container.RegisterManyForOpenGeneric(
            typeof(ICommandHandler<>),
            AppDomain.CurrentDomain.GetAssemblies());

        _container.RegisterManyForOpenGeneric(
            typeof(ICommandHandler<,>),
            AppDomain.CurrentDomain.GetAssemblies());

        // Validators
        _container.RegisterManyForOpenGeneric(
            typeof(IValidator<>),
            AppDomain.CurrentDomain.GetAssemblies());

        // Query Handlers
        _container.RegisterManyForOpenGeneric(
            typeof(IQueryHandler<,>),
            AppDomain.CurrentDomain.GetAssemblies());

        // Query Processor
        _container.Register<IQueryProcessor>(() => new QueryProcessor(_container));

        // Validation Decorators
        _container.RegisterDecorator(typeof(ICommandHandler<,>),
            typeof(ValidationCommandHandlerDecorator<,>),
            c => typeof(ICommandHandler<,>)
                    .MakeGenericType(c.ServiceType.GetGenericArguments())
                        .IsAssignableFrom(c.ImplementationType));


                    // Verify the container
        _container.Verify();

        //// Register the container as MVC IDependencyResolver
        DependencyResolver.SetResolver(new SimpleInjectorDependencyResolver(_container));

    }


InitializeIoC方法只是各种类型的注册,没有什么特别的。

InitializeIoC方法之后,RouteConfig调用使用通过SimpleInjector解析的类型的数据库调用。这似乎很好。

设置_manager字段时,似乎引发了错误,因为解析的类型使用IQueryHandler<SiteQuery, ISiteInfo>作为错误的来源。我不确定ISiteManager是否由SimpleInjector设置为单例,这是否是问题的根源。

具体的处理程序肯定存在(因为它确实起作用,所以该错误是间歇性的)。

我对此有些困惑!

这是错误和堆栈跟踪:


  错误页面
  
  无法注册IQueryHandler类型
  找到了。说明:在处理期间发生未处理的异常
  当前Web请求的执行。请检查堆栈跟踪
  有关该错误及其起源的更多信息
  码。
  
  异常详细信息:SimpleInjector.ActivationException:否
  IQueryHandler类型的注册可能是
  找到了。
  
  源错误:
  
  执行过程中产生了未处理的异常
  当前的Web请求。有关原产地和位置的信息
  可以使用下面的异常堆栈跟踪来识别异常。
  
  堆栈跟踪:
  
  [ActivationException:没有注册类型
  可以找到IQueryHandler。]
  SimpleInjector.Container.ThrowMissingInstanceProducerException(Type
  serviceType)+136 SimpleInjector.Container.GetInstance(类型
  serviceType)+76
  Pipeline.Crm.Services.QueryProcessor.QueryProcessor.Pipeline.Core.Services.Queries.Interfaces.IQueryProcessor.Process(IQuery
  查询)在c:\ Projects \ Pipeline中
  CMS \ Pipeline.CMS.Services \ QueryProcessor \ QueryProcessor.cs:29
  Pipeline.CMS.UI.Client.Management.SiteManager..ctor(IQueryProcessor
  c:\ Projects \ Pipeline中的queryProcessor,IConfiguration配置)
  CMS \ Pipeline.CMS.UI.Client \ SiteManager \ SiteManager.cs:23
  lambda_method(关闭)+148
  SimpleInjector.Lifestyles.SingletonLifestyleRegistrationBase 1.CreateInstanceWithNullCheck() +62 System.Lazy 1.CreateValue()+415 System.Lazy 1.LazyInitValue() +152 System.Lazy 1.get_Value()+75
  SimpleInjector.Lifestyles.SingletonLifestyleRegistrationBase 1.BuildExpression() +16 SimpleInjector.Registration.BuildExpression(InstanceProducer producer) +50
SimpleInjector.InstanceProducer.BuildExpressionInternal() +34
System.Lazy
1.CreateValue()+415 System.Lazy 1.LazyInitValue() +152 System.Lazy 1.get_Value()+75
  SimpleInjector.InstanceProducer.BuildExpression()+55
  
  [ActivationException:ISiteManager类型的注册委托
  引发了异常。找不到IQueryHandler类型的注册。]
  SimpleInjector.InstanceProducer.BuildExpression()+97
  SimpleInjector.InstanceProducer.VerifyExpressionBuilding()+31
  
  [InvalidOperationException:配置无效。创建
  ISiteManager类型的实例失败。的注册代表
  ISiteManager类型引发异常。没有注册类型
  可以找到IQueryHandler。]
  SimpleInjector.InstanceProducer.VerifyExpressionBuilding()+85
  SimpleInjector.Container.VerifyThatAllExpressionsCanBeBuilt(InstanceProducer []
  producersVerify)+28
  SimpleInjector.Container.VerifyThatAllExpressionsCanBeBuilt()+127
  SimpleInjector.Container.Verify()+109
  中的Pipeline.CMS.UI.Client.CmsApplication.InitializeIoC()
  c:\ Projects \ Pipeline CMS \ Pipeline.CMS.UI.Client \ CmsApplication.cs:156
  位于以下位置的Pipeline.CMS.UI.Client.CmsApplication.Application_Start()
  c:\ Projects \ Pipeline CMS \ Pipeline.CMS.UI.Client \ CmsApplication.cs:47
  位于以下位置的Pipeline.CMS.Client.MvcApplication.Application_Start()
  c:\ Projects \ Pipeline CMS \ Banerjee.Web \ Global.asax.cs:11
  
  [HttpException(0x80004005):配置无效。创造
  ISiteManager类型的实例失败。的注册代表
  ISiteManager类型引发异常。没有注册类型
  可以找到IQueryHandler。]
  System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext
  上下文,HttpApplication应用)+9936825
  System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr
  appContext,HttpContext上下文,MethodInfo []处理程序)+118
  System.Web.HttpApplication.InitSpecial(HttpApplicationState状态,
  MethodInfo []处理程序,IntPtr appContext,HttpContext上下文)+172
  System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr
  appContext,HttpContext上下文)+336
  System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr
  appContext)+296
  
  [HttpException(0x80004005):配置无效。创造
  ISiteManager类型的实例失败。的注册代表
  ISiteManager类型引发异常。没有注册类型
  可以找到IQueryHandler。]
  System.Web.HttpRuntime.FirstRequestInit(HttpContext上下文)+9915364
  System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext上下文)
  +101 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest
  wr,HttpContext上下文)+254

最佳答案

我的第一个直觉是,在注册过程中调用AppDomain.CurrentDomain.GetAssemblies()时,尚未加载包含查询处理程序实现的程序集。您的查询处理程序实现可能与IQueryHandler<,>接口位于不同的程序集中。在ASP.NET中,程序集的加载可能有点不确定。

尝试直接指定程序集,而不是调用AppDomain.CurrentDomain.GetAssemblies(),如下所示:

var assemblies = new[]
{
    typeof(SomeQueryHandlerImplementation).Assembly,
    typeof(SqlRepository<>).Assembly,
};

// Simple Injector v3.x
_container.Register(typeof(ICommandHandler<>), assemblies);
_container.Register(typeof(ICommandHandler<,>), assemblies);
_container.Register(typeof(IValidator<>), assemblies);
_container.Register(typeof(IQueryHandler<,>), assemblies);

// Simple Injector v2.x
_container.RegisterManyForOpenGeneric(typeof(ICommandHandler<>), assemblies);
_container.RegisterManyForOpenGeneric(typeof(ICommandHandler<,>), assemblies);
_container.RegisterManyForOpenGeneric(typeof(IValidator<>), assemblies);
_container.RegisterManyForOpenGeneric(typeof(IQueryHandler<,>), assemblies);


关于ValidationCommandHandlerDecorator装饰器注册的一个小注意事项。注册谓词始终返回true。因此,注册可以简化为以下内容:

_container.RegisterDecorator(typeof(ICommandHandler<,>),
    typeof(ValidationCommandHandlerDecorator<,>));

10-01 17:55