无法使用简单注入器为每个请求创建DbContext [英] Unable to Create DbContext per Request with Simple Injector

查看:93
本文介绍了无法使用简单注入器为每个请求创建DbContext的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当尝试注册我的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:

  1. 删除 SimpleInjectorInitializer.cs 类的[assembly: WebActivator.PreApplicationStartMethod](第一行).
  2. 在全局asax的Application_Start()事件中添加对SimpleInjectorInitializer.Initialize()方法的调用.
  1. Remove the [assembly: WebActivator.PreApplicationStartMethod] (top line) of the SimpleInjectorInitializer.cs class.
  2. Add a call to the SimpleInjectorInitializer.Initialize() method in the Application_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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆