无法使用简单注入器为每个请求创建DbContext [英] Unable to Create DbContext per Request with Simple Injector
问题描述
当尝试注册我的DbContext时,Simple Inject引发以下异常.
Simple Inject is throwing the following exception when attempting to register my DbContext.
提供的连接字符串无效,因为它包含的映射或元数据信息不足. 参数名称:connectionString
The supplied connection string is not valid, because it contains insufficient mapping or metadata information. Parameter name: connectionString
我是DI的新手,可能会错过一些显而易见的东西.连接字符串看起来不错.通常用于创建DbContext的是相同的.我正在此处
I'm new to DI and could be missing something fairly obvious. The connection string looks fine. It is the same one that gets used to create the DbContext normally. I was attempting the solution here
public static class SimpleInjectorInitializer
{
/// <summary>Initialize the container and register
// it as MVC3 Dependency Resolver.</summary>
public static void Initialize()
{
var container = new Container();
InitializeContainer(container);
container.RegisterMvcControllers(
Assembly.GetExecutingAssembly());
container.RegisterMvcAttributeFilterProvider();
container.Verify();
DependencyResolver.SetResolver(
new SimpleInjectorDependencyResolver(container));
}
private static void InitializeContainer(
Container container)
{
}
}
Update: I still haven't solved my issue, but it is very similar to this issue with Ninject
堆栈跟踪:
System.InvalidOperationException was unhandled by user code
Message=The configuration is invalid. Creating the instance for type _AccountController failed. Error occurred while trying to get an instance of type _AccountController. The type initializer for 'Web.Controllers._AccountController' threw an exception.
Source=SimpleInjector
StackTrace:
at SimpleInjector.Helpers.Verify(IInstanceProducer instanceProducer, Type serviceType)
at SimpleInjector.Container.ValidateRegistrations()
at SimpleInjector.Container.Verify()
at Web.App_Start.SimpleInjectorInitializer.Initialize() in C:\workspace\BrowsarServer\QARSite\Web\App_Start\SimpleInjectorInitializer.cs:line 24
InnerException: SimpleInjector.ActivationException
Message=Error occurred while trying to get an instance of type _AccountController. The type initializer for 'Web.Controllers._AccountController' threw an exception.
Source=SimpleInjector
StackTrace:
at SimpleInjector.InstanceProducers.InstanceProducer.ThrowErrorWhileTryingToGetInstanceOfType(Exception innerException)
at SimpleInjector.InstanceProducers.InstanceProducer.GetInstance()
at SimpleInjector.Helpers.Verify(IInstanceProducer instanceProducer, Type serviceType)
InnerException: System.TypeInitializationException
Message=The type initializer for 'Web.Controllers._AccountController' threw an exception.
Source=Web
TypeName=Web.Controllers._AccountController
StackTrace:
at Web.Controllers._AccountController..ctor()
at lambda_method(Closure )
at SimpleInjector.InstanceProducers.InstanceProducer.GetInstance()
InnerException: System.ArgumentException
Message=The supplied connection string is not valid, because it contains insufficient mapping or metadata information.
Parameter name: connectionString
Source=System.Data.Entity
ParamName=connectionString
StackTrace:
at System.Data.Objects.ObjectContext..ctor(EntityConnection connection, Boolean isConnectionConstructor)
at System.Data.Objects.ObjectContext..ctor(String connectionString, String defaultContainerName)
at Web.Models.BrowsarEntities..ctor() in C:\workspace\BrowsarServer\QARSite\Web\Models\Browsar.Designer.cs:line 90
at Web.Controllers._AccountController..cctor() in C:\workspace\BrowsarServer\QARSite\Web\Controllers\_AccountController.cs:line 15
InnerException: System.InvalidOperationException
Message=Unable to determine application context. The ASP.NET application path could not be resolved.
Source=System.Data.Entity
StackTrace:
at System.Data.Metadata.Edm.AspProxy.GetBuildManagerReferencedAssemblies()
at System.Data.Metadata.Edm.DefaultAssemblyResolver.GetAllDiscoverableAssemblies()
at System.Data.Metadata.Edm.DefaultAssemblyResolver.GetWildcardAssemblies()
at System.Data.Metadata.Edm.MetadataArtifactLoaderCompositeResource.LoadResources(String assemblyName, String resourceName, ICollection`1 uriRegistry, MetadataArtifactAssemblyResolver resolver)
at System.Data.Metadata.Edm.MetadataArtifactLoaderCompositeResource.CreateResourceLoader(String path, ExtensionCheck extensionCheck, String validExtension, ICollection`1 uriRegistry, MetadataArtifactAssemblyResolver resolver)
at System.Data.Metadata.Edm.MetadataArtifactLoader.Create(String path, ExtensionCheck extensionCheck, String validExtension, ICollection`1 uriRegistry, MetadataArtifactAssemblyResolver resolver)
at System.Data.Metadata.Edm.MetadataCache.SplitPaths(String paths)
at System.Data.Common.Utils.Memoizer`2.<>c__DisplayClass2.<Evaluate>b__0()
at System.Data.Common.Utils.Memoizer`2.Result.GetValue()
at System.Data.Common.Utils.Memoizer`2.Evaluate(TArg arg)
at System.Data.EntityClient.EntityConnection.GetMetadataWorkspace(Boolean initializeAllCollections)
at System.Data.Objects.ObjectContext.RetrieveMetadataWorkspaceFromConnection()
at System.Data.Objects.ObjectContext..ctor(EntityConnection connection, Boolean isConnectionConstructor)
InnerException: System.Reflection.TargetInvocationException
Message=Exception has been thrown by the target of an invocation.
Source=mscorlib
StackTrace:
at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks)
at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture)
at System.Data.Metadata.Edm.AspProxy.GetBuildManagerReferencedAssemblies()
InnerException: System.InvalidOperationException
Message=This method cannot be called during the application's pre-start initialization stage.
Source=System.Web
StackTrace:
at System.Web.Compilation.BuildManager.EnsureTopLevelFilesCompiled()
at System.Web.Compilation.BuildManager.GetReferencedAssemblies()
InnerException:
推荐答案
根本原因隐藏在内部异常中.检查堆栈跟踪时,您将能够找到造成这种情况的原因.原因在于以下两个内部异常:
The root cause is burried deep down in the inner exceptions. When inspecting the stack trace, you will be able to find the cause of this. The reason is in the following two inner exceptions:
InvalidOperationException:无法确定应用程序上下文. 无法解析ASP.NET应用程序路径.
InvalidOperationException: Unable to determine application context. The ASP.NET application path could not be resolved.
和:
InvalidOperationException:在调用过程中无法调用此方法 应用程序的启动前初始化阶段.
InvalidOperationException: This method cannot be called during the application's pre-start initialization stage.
换句话说,此异常是由计时问题引起的.我不确定是否可以更改连接字符串来解决此问题,但是您也可以将初始化移动到稍后启动应用程序的那一刻.您可以按照以下步骤进行操作:
In other words, this exception is caused by a timing problem. I'm not sure if you can change your connection string to solve this, but you can also move your initalization to a later moment in starting the application. You can do this as follows:
- 删除 SimpleInjectorInitializer.cs 类的
[assembly: WebActivator.PreApplicationStartMethod]
(第一行). - 在全局asax的
Application_Start()
事件中添加对SimpleInjectorInitializer.Initialize()
方法的调用.
- Remove the
[assembly: WebActivator.PreApplicationStartMethod]
(top line) of the SimpleInjectorInitializer.cs class. - Add a call to the
SimpleInjectorInitializer.Initialize()
method in theApplication_Start()
event of the global asax.
这样做之后,在预初始化状态之后完成对象图的初始化(尤其是验证),这对于ASP.NET环境中的EF来说似乎还为时过早.
After doing this, initializing (and especially, verifying) of the object graph is done after the pre-init state, which seems to be too early for EF in an ASP.NET environment.
另一个选择是从SimpleInjectorInitializer.Initialize
方法中删除container.Verify();
调用,因为这是杀死您的早期验证过程.但是,请先阅读验证容器的配置,然后再查看替代方法.
Another option is to remove the container.Verify();
call from the SimpleInjectorInitializer.Initialize
method, since it is the early verification process that is killing you. However, please read this Verify the container’s configuration first, to see alternatives, before doing so.
这篇关于无法使用简单注入器为每个请求创建DbContext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!