我有一个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:No 注册类型IQueryHandler可能是 找到。
来源错误:
执行期间生成了未处理的异常 当前的网络请求。有关的来源和位置的信息 可以使用下面的异常堆栈跟踪来识别异常。
堆栈追踪:
[ActivationException:没有注册类型 可以找到IQueryHandler。] SimpleInjector.Container.ThrowMissingInstanceProducerException(类型 serviceType)+136 SimpleInjector.Container.GetInstance(Type 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 queryProcessor,IConfiguration配置)在c:\ Projects \ Pipeline中 CMS \ Pipeline.CMS.UI.Client \ SiteManager \ SiteManager.cs:23
lambda_method(关闭)+148
SimpleInjector.Lifestyles.SingletonLifestyleRegistrationBase1.CreateInstanceWithNullCheck() +62 System.Lazy
1.CreateValue()+415 System.Lazy1.LazyInitValue() +152 System.Lazy
1.get_Value()+75
SimpleInjector.Lifestyles.SingletonLifestyleRegistrationBase1.BuildExpression() +16 SimpleInjector.Registration.BuildExpression(InstanceProducer producer) +50
1.CreateValue()+415 System.Lazy
SimpleInjector.InstanceProducer.BuildExpressionInternal() +34
System.Lazy1.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 [] producerToVerify)+28
SimpleInjector.Container.VerifyThatAllExpressionsCanBeBuilt()+ 1277 SimpleInjector.Container.Verify()+ 109 Pipeline.CMS.UI.Client.CmsApplication.InitializeIoC()in c:\ Projects \ Pipeline CMS \ Pipeline.CMS.UI.Client \ CmsApplication.cs:156 Pipeline.CMS.UI.Client.CmsApplication.Application_Start()in c:\ Projects \ Pipeline CMS \ Pipeline.CMS.UI.Client \ CmsApplication.cs:47
Pipeline.CMS.Client.MvcApplication.Application_Start()in c:\ Projects \ Pipeline CMS \ Banerjee.Web \ Global.asax.cs:11[HttpException(0x80004005):配置无效。创建 类型ISiteManager的实例失败。注册代表 类型ISiteManager引发了异常。没有注册类型 可以找到IQueryHandler。] System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext的 上下文,HttpApplication app)+9936825
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr的 appContext,HttpContext上下文,MethodInfo []处理程序)+118
System.Web.HttpApplication.InitSpecial(HttpApplicationState状态, MethodInfo [] handlers,IntPtr appContext,HttpContext context)+172
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr的 appContext,HttpContext context)+336
System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr的 appContext)+296[HttpException(0x80004005):配置无效。创建 类型ISiteManager的实例失败。注册代表 类型ISiteManager引发了异常。没有注册类型 可以找到IQueryHandler。] System.Web.HttpRuntime.FirstRequestInit(HttpContext context)+9915364 System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +101 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest) wr,HttpContext context)+254
答案 0 :(得分:3)
我的第一个直觉是,在注册过程中调用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<,>));