У меня есть приложение .Net Core Web API. Есть некоторый метод Get в контроллере и внедренный IRepositoryProviderFactory. Ничего особенного.
[ApiController]
public class DataController : ControllerBase
{
private readonly ILogger<DataController> _logger;
private readonly IRepositoryProviderFactory _repositoryProviderFactory;
#region ctor
/// <summary>
/// ctor
/// </summary>
public DataController(ILogger<DataController> logger, IRepositoryProviderFactory repositoryProviderFactory)
{
_logger = logger;
_repositoryProviderFactory = repositoryProviderFactory;
}
[HttpPost]
public async Task<IActionResult> GetData([FromBody] SearchModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
try
{
var data = await _repositoryProviderFactory.GetDataAsync(model);
return Ok(data);
}
catch (Exception ex)
{
return StatusCode((int)HttpStatusCode.InternalServerError);
}
}
}
Существуют репозитории, основанные на одном и том же интерфейсе для получения данных из разных источников данных.
public Repository1: IDataRepository {}
public Repository2: IDataRepository {}
public Repository3: IDataRepository {}
Я использую DI, поэтому все части зарегистрированы в службах как Scoped или Transient. Некоторые репозитории используют EntityFramework.
services.AddScoped<IDataRepository, Repository1>();
services.AddScoped<IDataRepository, Repository2>();
services.AddScoped<IDataRepository, Repository3>();
Хорошо, теперь мне нужно реализовать RepositoryProviderFactory для возврата репозитория. Но есть одна необходимая функциональность: она должна возвращать для каждого звонка разные репозитории .
Я ввел IEnumerable, и мне нужно вернуть Repository1, Repository2, Repository3 и снова Repository1, ... и т. Д. Таким образом, все репозитории используются одновременно.
/// <summary>
/// ctor
/// </summary>
public RepositoryProviderFactory(
ILogger<RepositoryProviderFactory> logger,
IEnumerable<IDataRepository> dataRepositories)
{
_logger = logger;
_dataRepositories = dataRepositories;
}
public IDataRepository GetRepository()
{
// TODO: Logic to cycle repositories
var instance = dataRepositories.Where();
return instance;
}
Как это сделать?
Фабрика не может быть зарегистрирована как Singleton, потому что у репозиториев есть другие зависимости, у которых есть Scoped Lifetime (DbContext и т. Д.)
Как я могу создать какой-то потокобезопасный одноэлементный объект, чтобы иметь возможность сохранять последний использованный репозиторий и обслуживать другой для другого вызова?