5

Simple Inject is throwing the following exception when attempting to register my DbContext.

The supplied connection string is not valid, because it contains insufficient mapping or metadata information. Parameter name: connectionString

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

Stack Trace:

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: 
Community
  • 1
  • 1
Josh C
  • 4,471
  • 2
  • 22
  • 21
  • Simple Injector does not throw exceptions like these. Look at your stacktrace where this exception is coming from (tip: look at the inner exception). Probably it's your `new DbContext` that is failing. – Steven Jun 15 '12 at 06:21
  • Note: Always provide the exception and stack trace in your question if you want a good answer. – Steven Jun 15 '12 at 17:29
  • Added the stack trace. I also found a very similar unsolved issue with Ninject. – Josh C Jun 15 '12 at 23:51

3 Answers3

10

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: Unable to determine application context. The ASP.NET application path could not be resolved.

and:

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. 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.

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.

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.

Steven
  • 151,500
  • 20
  • 287
  • 393
  • I realize there is some bad code in there. Thus the reason I'm implementing DI. My connection string works fine without Simple Injector, does it still make sense that my connection string is the problem? – Josh C Jun 16 '12 at 00:35
1

Although you use a class DbContext it looks like it is derived from ObjectContext. In that case you should use an EntityConnectionStringBuilder to build the connection string.

Gert Arnold
  • 93,904
  • 24
  • 179
  • 256
0

You may be missing some of the metadata information in your connection string. For example entity framework has some special metadata in the connection string, see sample below:

<add name="MyEntities" connectionString="metadata=res://*/MyEntitiesStore.csdl|res://*/MyEntitiesStore.ssdl|res://*/MyEntitiesStore.msl;provider=System.Data.SqlClient;provider connection string=&quot;Data Source=<your server>;Initial Catalog=<your DB>;Integrated Security=False;User ID=<user>;Password=<pass>;MultipleActiveResultSets=True&quot;" 
   providerName="System.Data.EntityClient" />
fenix2222
  • 4,323
  • 3
  • 31
  • 54
  • No, I cut and tried cutting and pasting my connection string in manually and still no go. – Josh C Jun 15 '12 at 00:03
  • @JoshC are you using SQL Azure? It is basically saying that your connection string is incorrect. Can I see it? – fenix2222 Jun 15 '12 at 01:52
  • No. I'm not using Azure. metadata=res://*/Models.Database.csdl|res://*/Models.Database.ssdl|res://*/Models.Database.msl;provider=System.Data.SqlClient;provider connection string="data source=xxx.xxx.xx;User ID=xxxxxxx;Password=xxxxxxx;initial catalog=DatabaseDev;multipleactiveresultsets=True;App=EntityFramework"" – Josh C Jun 15 '12 at 16:50