在 Unity 解析依赖项时,底层提供程序在 Open 上失败
The underlying provider failed on Open at the time Unity resolve the dependencies
我正在使用与 Unity 配合使用的 MVC 应用程序来注册我的项目的所有依赖项。我也在为 DAL 使用 Entity Framework。
在我的本地机器上,应用程序 运行ning 正常,但当我部署在服务器上时,当 Unity 尝试解决依赖关系时,我收到错误消息。
基础提供程序打开失败。 ... 在发生异常时,容器是: Resolving Class mapped from IClass ... Calling constructor of MyDbContext(System.String connectionName)
1-这与连接字符串结构有关系吗?
下面是我的连接字符串
<add name="DBConnection" connectionString="Server=MyServer;Database=MyDatabase;Trusted_Connection=True;MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />
此时我无权访问数据库以检查 IIS 用户是否有服务器上的权限以 运行 任何查询,但假设没有,这是否有任何与 Unity 尝试解析连接字符串时的错误有什么关系?
2- Unity 在尝试解析 DBContext 后是否会尝试打开与 DB 的连接?
这是我注入参数的方式
var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString;
container.RegisterType<IUnitOfWork, MyDbContext>(
Activator.CreateInstance<T>(),
new InjectionConstructor(connectionString));
您的问题很可能与您在生产环境中的应用程序池身份无法访问数据库有关。一旦需要,Unity 会创建所有依赖 类 的实例。因此,如果您的 Class 需要 IUnitOfWork,unity 会尝试实例化 MyDbContext。
让我指出,您不应该首先将实体上下文 (MyDbContext) 的实例注册为单例 - entity framework 上下文不是线程安全的 (Entity Framework Thread Safety),DI 也是关键基础设施的一部分(不应该有 IO 调用 - 例如打开可能出错的数据库)
而是使用类似
的东西
public interface IEntityContextProvider {
public MyDbContext CreateContext();
}
public class EntityContextProvider : IEntityContextProvider {
public MyDbContext CreateContext() {
return new MyDbContext("ef connection string");
}
}
用法:
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
}
}
}
此外,您的连接字符串看起来很像 "ordinary" 连接字符串 - 即到数据库的连接字符串 wout entity framework - 我缺少其中的元数据。代码明智的通常是
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();
}
我正在使用与 Unity 配合使用的 MVC 应用程序来注册我的项目的所有依赖项。我也在为 DAL 使用 Entity Framework。 在我的本地机器上,应用程序 运行ning 正常,但当我部署在服务器上时,当 Unity 尝试解决依赖关系时,我收到错误消息。
基础提供程序打开失败。 ... 在发生异常时,容器是: Resolving Class mapped from IClass ... Calling constructor of MyDbContext(System.String connectionName)
1-这与连接字符串结构有关系吗?
下面是我的连接字符串
<add name="DBConnection" connectionString="Server=MyServer;Database=MyDatabase;Trusted_Connection=True;MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />
此时我无权访问数据库以检查 IIS 用户是否有服务器上的权限以 运行 任何查询,但假设没有,这是否有任何与 Unity 尝试解析连接字符串时的错误有什么关系?
2- Unity 在尝试解析 DBContext 后是否会尝试打开与 DB 的连接?
这是我注入参数的方式
var connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["DBConnection"].ConnectionString;
container.RegisterType<IUnitOfWork, MyDbContext>(
Activator.CreateInstance<T>(),
new InjectionConstructor(connectionString));
您的问题很可能与您在生产环境中的应用程序池身份无法访问数据库有关。一旦需要,Unity 会创建所有依赖 类 的实例。因此,如果您的 Class 需要 IUnitOfWork,unity 会尝试实例化 MyDbContext。
让我指出,您不应该首先将实体上下文 (MyDbContext) 的实例注册为单例 - entity framework 上下文不是线程安全的 (Entity Framework Thread Safety),DI 也是关键基础设施的一部分(不应该有 IO 调用 - 例如打开可能出错的数据库)
而是使用类似
的东西public interface IEntityContextProvider {
public MyDbContext CreateContext();
}
public class EntityContextProvider : IEntityContextProvider {
public MyDbContext CreateContext() {
return new MyDbContext("ef connection string");
}
}
用法:
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
}
}
}
此外,您的连接字符串看起来很像 "ordinary" 连接字符串 - 即到数据库的连接字符串 wout entity framework - 我缺少其中的元数据。代码明智的通常是
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();
}