#class #dependency-injection #entity-framework-core #blazor-server-side
Вопрос:
У меня проблема с ДИ. У меня есть пользовательский класс, который должен импортировать некоторые данные в базу данных через службу. Если я использую эту службу в компоненте Blazor, она хорошо работает с @injection.
Но я не могу использовать его в своем пользовательском классе. Я пробовал это так
public class ImportXml
{
private readonly AccountService _accountService;
public ImportXml(AccountService accountService)
{
_accountService = accountService;
}
public ImportXml(List<Transaction> transactions, Account account)
{
if(account.Transactions==null)
{
account.Transactions = new List<Transaction>();
}
account.Transactions.AddRange(transactions);
_accountService.UpdateAccountsAsync(account);
}
}
В startup.cs сервис зарегистрирован таким образом.
services.AddScoped<AccountService>();
Если я вызову ImportXML _accountService, значение будет равно нулю.
Мой текущий обходной путь заключается в том, чтобы просто отправить службу как часть параметров. Но я хотел бы иметь рабочее решение с DI.
public class ImportXml
{
public ImportXml(List<Transaction> transactions, Account account, AccountService accountService)
{
if(account.Transactions==null)
{
account.Transactions = new List<Transaction>();
}
account.Transactions.AddRange(transactions);
accountService.UpdateAccountsAsync(account);
}
}
Большое спасибо
Ответ №1:
У вас здесь есть пара проблем.
- Для того, чтобы ImportXML получал учетную запись через DI, ImportXML также должен быть предоставлен контейнером DI.
- Вы используете второй конструктор, чтобы попытаться выполнить действие, а не метод. Конструкторы следует просто использовать для настройки класса, а не для выполнения каких-либо действий, особенно длительных действий, таких как обновление базы данных. Кроме того, обратите внимание, что конструктор не является асинхронным.
Измените свой класс ImportXML
public class ImportXml
{
private readonly AccountService _accountService;
// This it the constructor, so just set the object up
public ImportXml(AccountService accountService)
{
_accountService = accountService;
}
// This is the method to perform the update
public async Task DoAccountUpdateAsync(
List<Transaction> transactions,
Account account)
{
if(account.Transactions==null)
{
account.Transactions = new List<Transaction>();
}
account.Transactions.AddRange(transactions);
await _accountService.UpdateAccountsAsync(account);
}
}
Зарегистрируйте как AccountService, так и ImportXML
services.AddScoped<AccountService>();
services.AddScoped<ImportXml>();
Из клиента введите ImportXML и используйте эту службу.
Когда ImportXML вводится, его параметры конструктора (AccountService) будут автоматически предоставлены DI и введены в ImportXML.
@inject ImportXML ImportXML
<button @onclick=@HandleClick>Perform Account Update</button>
@code {
List<Transactions> _transactionsForMethod;
Account _accountForMethod;
async Task HandleClick()
{
await ImportXML.DoAccountUpdateAsync(
_transactionsForMethod,
_accoountForMethod);
}
}
Комментарии:
1. Спасибо за совет, я его проверю.