简体   繁体   中英

The underlying provider failed on Open at the time Unity resolve the dependencies

I am using an MVC Application that works with Unity to register all the dependencies of my project. I am also using Entity Framework for the DAL. In my local machine the application is running fine but at the time I deployed on the server I am receiving an error when Unity is trying to resolve the dependencies.

The underlying provider failed on Open. ... At the time of the exception, the container was: Resolving Class mapped from IClass ... Calling constructor of MyDbContext(System.String connectionName)

1- Does this have a relation with the connection string structure?

Bellow is my connection string

<add name="DBConnection" connectionString="Server=MyServer;Database=MyDatabase;Trusted_Connection=True;MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />

At this moment I don't have the access to the DB to check if the IIS user has the privileges on the server to run any query, but supposing it doesn't, does this has any relation with the error at the time Unity is trying to resolve the connection string?

2- Does Unity try to open a connection to the DB once it tries to resolve the DBContext?

Here is how I am injecting the parameters

var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString;

container.RegisterType<IUnitOfWork, MyDbContext>(
                Activator.CreateInstance<T>(),
                new InjectionConstructor(connectionString));

Your problem is most probably tied to fact that your application pool identity on production doesn't have access to the db. Unity creates instance of all dependent classes once the need arises. So if your Class needs IUnitOfWork, unity tries to instantiate MyDbContext.

Let me point out that you shouldn't register instance of entity context (MyDbContext) as singleton in first place - entity framework context is not thread-safe ( Entity Framework Thread Safety ), also DI is part of critical infrastructure (there shouldn't be IO calls - such as opening the db that can go wrong)

Instead use something like

public interface IEntityContextProvider {
   public MyDbContext CreateContext();
}
public class EntityContextProvider : IEntityContextProvider  {
   public MyDbContext CreateContext() {
     return new MyDbContext("ef connection string");
   }
}

Usage:

public class SomeClassUsingEF {
  // DI
  private readonly IEntityContextProvider _entityContextProvider;
  // DI
  public SomeClassUsingEF(IEntityContextProvider entityContextProvider)
  {
     if (entityContextProvider == null)
       throw new ArgumentNullException(nameof(entityContextProvider));
     _entityContextProvider = entityContextProvider;
  }

  public void SomeQueryToDB() {
    using(var context = _entityContextProvider.CreateContext()) {
      // select/insert/updates here
    }
  }
}

Also you connection string looks a lot like "ordinary" connection string - ie connection string to db wout entity framework - I'm missing the metadata in it. Code wise its usually something like

 private string GetEFConnectionString()
 {
    string providerName = "System.Data.SqlClient";
    string serverName = @".\SQL2008";
    string databaseName = "my-db";

    // Initialize the connection string builder for the
    // underlying provider.
    var sqlBuilder = new SqlConnectionStringBuilder();

    // Set the properties for the data source.
    sqlBuilder.DataSource = serverName;
    sqlBuilder.InitialCatalog = databaseName;
    sqlBuilder.IntegratedSecurity = true;

    // Build the SqlConnection connection string.
    string providerString = sqlBuilder.ToString();

    // Initialize the EntityConnectionStringBuilder.
    var entityBuilder = new EntityConnectionStringBuilder();

    // Set the provider name.
    entityBuilder.Provider = providerName;

    // Set the provider-specific connection string.
    entityBuilder.ProviderConnectionString = providerString;

    // Set the Metadata location.
    entityBuilder.Metadata = @"res://*/Model.csdl|
      res://*/Model.ssdl|
      res://*/Model.msl";
    return entityBuilder.ToString();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM