【问题标题】:Exception in Scope Implementation范围实施中的例外
【发布时间】:2022-01-07 03:06:13
【问题描述】:

我正在尝试遵循本教程Repository pattern without ORM,它看起来很有前途,并且做了与教程中完全相同的事情。我的计划很简单,只是从数据库中检索数据:

型号:

public class TeamDetails
{
    public int TeamId { get; set; }
    public string TeamName { get; set; }
}

public class DataConnection
{
    public string DefaultConnection { get; set; }
}

Ado 存储库:

public abstract class AdoRepository<T> where T : class
{
    
    private static SqlConnection _connection;
    string connectionString = "Data Source=.;Initial Catalog=DemoApp;Trusted_Connection=True";

    public AdoRepository(string connectionString)
    {
        _connection = new SqlConnection(connectionString);
    }

    public virtual T PopulateRecord(SqlDataReader reader)
    {
        return null;
    }
    
    protected List<T> GetRecords(SqlCommand command)
    {
        var list = new List<T>();
        command.Connection = _connection;
        _connection.Open();
        try
        {
            var reader = command.ExecuteReader();
            try
            {
                while (reader.Read())
                    list.Add(PopulateRecord(reader));
            }
            finally
            {
                // Always call Close when done reading.
                reader.Close();
            }
        }
        finally
        {
            _connection.Close();
        }
        return list;
    }

    protected T GetRecord(SqlCommand command)
    {
        T record = null;
        command.Connection = _connection;
        _connection.Open();
        try
        {
            var reader = command.ExecuteReader();
            try
            {
                while (reader.Read())
                {
                    record = PopulateRecord(reader);
                    break;
                }
            }
            finally
            {
                // Always call Close when done reading.
                reader.Close();
            }
        }
        finally
        {
            _connection.Close();
        }
        return record;
    }
    
    protected IEnumerable<T> ExecuteStoredProc(SqlCommand command)
    {
        var list = new List<T>();
        command.Connection = _connection;
        command.CommandType = CommandType.StoredProcedure;
        _connection.Open();
        try
        {
            var reader = command.ExecuteReader();
            try
            {
                while (reader.Read())
                {
                    var record = PopulateRecord(reader);
                    if (record != null) list.Add(record);
                }
            }
            finally
            {
                // Always call Close when done reading.
                reader.Close();
            }
        }
        finally
        {
            _connection.Close();
        }
        return list;
    }
}

界面:

public interface ITeam
{
    List<TeamDetails> GetAllTeams();
}

实现团队存储库:

public class TeamRepository : AdoRepository<TeamDetails>, ITeam
{
    public TeamRepository(string connectionString)
        : base(connectionString)
    {
    }

    public List<TeamDetails> GetAllTeams()
    {
        using (var command = new SqlCommand("select * from Team"))
        {
            return GetRecords(command);
        }
    }

    public override TeamDetails PopulateRecord(SqlDataReader reader)
    {
        return new TeamDetails
        {
            TeamId = Convert.ToInt32(reader.GetString(0)),
            TeamName = reader.GetString(1)
        };
    }
}

一个服务接口:

public interface ITeamRepoService
{
    List<TeamDetails> GetAllTeams();
}

实施服务:

public class ITeamService : ITeamRepoService
{
    private readonly ITeam _repository;

    public ITeamService(IOptions<DataConnection> options)
    {
        var connection = options.Value;
        _repository = new TeamRepository(connection.DefaultConnection);
    }

    public List<TeamDetails> GetAllTeams()
    {
        return _repository.GetAllTeams();
    }
}

最后在控制器中调用如下:

 private readonly ITeamService _service;
 private readonly ILogger<WeatherForecastController> _logger;

 public WeatherForecastController(ILogger<WeatherForecastController> logger, ITeamService service)
 {
    _logger = logger;
    _service = service;
 }

[HttpGet]
public async Task<ActionResult<IEnumerable<TeamDetails>>> Index()
{
  var teams = _service.GetAllTeams();

  return Ok(teams);
}

问题是当我运行代码时,它会从 Startup.cs 文件中引发异常:

Some services are not able to be constructed (Error while validating the service descriptor 'ServiceType: TodoApi.Interface.ITeam Lifetime: Scoped ImplementationType: TodoApi.Repository.TeamRepository': Unable to resolve service for type 'System.String' while attempting to activate 'TodoApi.Repository.TeamRepository'.)

在启动文件中,我做了以下但没有成功:

services.Configure<DataConnection>(Configuration.GetSection("AppDbConnection"));

services.AddTransient<ITeamRepoService, ITeamService>();
services.AddTransient<ITeam, TeamRepository>();

有什么办法解决吗?

【问题讨论】:

  • 您的 TeamRepository 在构造函数中需要一个字符串,而您还没有告诉 DI 如何构造该对象,因此它试图从 DI 获取一个字符串,这不起作用。向 AddTransient 添加一个构造对象的函数,或者将其更改为使用配置/选项对象而不是字符串。
  • 你能分享一个我可以研究的样本吗?
  • 嗨@user8512043,有什么更新吗?
  • 工作就像一个魅力。非常感谢@Rena。

标签: c# asp.net-core .net-core asp.net-core-3.1


【解决方案1】:

正如@juunas 所说,您的 TeamRepository 需要一个字符串(connectionString),请在下面更改您的代码:

services.AddTransient<ITeam, TeamRepository>(_ => new TeamRepository("connectionString here"));

参考:

https://docs.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-6.0#disposal-of-services

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-07
    • 1970-01-01
    • 2012-12-02
    • 2019-06-22
    • 1970-01-01
    • 2023-03-19
    相关资源
    最近更新 更多