依赖注入IDbConnection SqlConnection

时间:2018-05-16 08:58:39

标签: c# asp.net-core dependency-injection

我提出此异常有时

System.InvalidOperationException: 'The ConnectionString property has not been initialized.'

我使用内置的依赖注入:

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<IDbConnection>(db => new SqlConnection(
                    Configuration.GetConnectionString("AppConnectionString")));

    services.AddScoped<IAppConfigurationRepository, AppConfigurationRepository>();
    services.AddScoped<IHomeworkingRequestRepository, HomeworkingRequestRepository>();
    services.AddScoped<IEmployeeRepository, EmployeeRepository>();
    services.AddScoped<IEmployeeService, EmployeeService>();
    services.AddScoped<IHomeworkingRequestService, HomeworkingRequestService>();
    services.AddMvc();
}

之前,我已经有了这个错误。代码services.AddScoped<IDbConnection>我更改为services.AddTransient<IDbConnection>并解决了问题。但现在我又错了。

修改

发生异常时请查找代码:

public class EmployeeRepository : IEmployeeRepository
{
    private readonly IDbConnection _connection;

    public EmployeeRepository(IDbConnection connection)
    {
        _connection = connection;
    }

    public IEnumerable<Employee> GetAllActiveEmployees()
    {
        string query = @"
           SELECT
               FirstName
              ,LastName
              ,BusinessUnit
          FROM Employees";

        using (var db = _connection)
        {
            _connection.Open(); // <-- The exception is thrown here
            return db.Query<Employee>(query);
        }
    }
 }

请同时找到完整的堆栈跟踪:

at System.Data.SqlClient.SqlConnection.PermissionDemand()
   at System.Data.SqlClient.SqlConnectionFactory.PermissionDemand(DbConnection outerConnection)
   at System.Data.ProviderBase.DbConnectionInternal.TryOpenConnectionInternal(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.ProviderBase.DbConnectionClosed.TryOpenConnection(DbConnection outerConnection, DbConnectionFactory connectionFactory, TaskCompletionSource`1 retry, DbConnectionOptions userOptions)
   at System.Data.SqlClient.SqlConnection.TryOpen(TaskCompletionSource`1 retry)
   at System.Data.SqlClient.SqlConnection.Open()
   at Homeworking.Dal.EmployeeRepository.GetAllActiveEmployees() in C:\Users\florian.nouri\source\repos\Homeworking\Homeworking.Repository\EmployeeRepository.cs:line 42
   at Homeworking.Service.EmployeeService.GetAllEmployees() in C:\Users\florian.nouri\source\repos\Homeworking\Homeworking.Service\EmployeeService.cs:line 22
   at Homeworking.Service.HomeworkingRequestService.GetAllEmployees() in C:\Users\florian.nouri\source\repos\Homeworking\Homeworking.Service\HomeworkingRequestService.cs:line 23
   at Homeworking.Web.Controllers.AppController.Index() in C:\Users\florian.nouri\source\repos\Homeworking\Homeworking.Web\Controllers\AppController.cs:line 22
   at lambda_method(Closure , Object , Object[] )
   at Microsoft.Extensions.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.SyncActionResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()

1 个答案:

答案 0 :(得分:3)

using (var db = _connection)

这很糟糕。您为同一连接创建一个新变量,因此在使用完成后,您的连接将被释放。你不应该这样做。如果您使用容器来创建东西,容器应该处理它不再需要的那些实例。

最有可能发生的事情是你的_connection变量被处理掉了,任何从容器获取连接的类(在Scoped的情况下)或任何已经有这个变量的类已经被第二次使用了因为它是一个实例字段,将使用已经处理过的连接。