У меня есть полностью асинхронный API MVC, который внедряет интерфейс во все его контроллеры:
public PageController(IDataAdapter dataAdapter) {
_dataAdapter = dataAdapter;
}
Реализация интерфейса должна иметьмаркер доступа установлен в его объекте SQLConnection. Этот токен доступа необходим для безопасного доступа к управляемой идентификации (см. https://docs.microsoft.com/en-us/azure/app-service/app-service-web-tutorial-connect-msi).. Этот токен должен быть установлен при создании контроллера, то есть при каждом новом запросе. Токен может изменяться, поэтому мы не можем его иметь. статическое значение. Вот что мы имеем сегодня в реализации интерфейса:
public partial class DataAdapter : BaseEntityDataAdapter, IDataAdapter {
AppInsightsLogger _log = new AppInsightsLogger();
#region Constructor
/// <summary>
/// Instantiate the data adapter and pull out the dsn information
/// </summary>
public DataAdapter() : base("db") {
try {
var conn = base.Database.Connection as System.Data.SqlClient.SqlConnection;
conn.AccessToken = (new AzureServiceTokenProvider()).GetAccessTokenAsync("https://database.windows.net/").Result;
} catch (Exception ex) {
_log.LogError(ex);
throw;
}
}
}
Вы можете видеть, что мы используем .Result для оценки асинхронной операции, которая, в свою очередь, фактически выполняетсяэто синхронно. Я знаю, что я должен использовать фабричный шаблон, как показано ниже:
public async Task<DataAdapter> ConstructAdapterAsync() {
try {
DataAdapter da = new DataAdapter();
var conn = da.Database.Connection as System.Data.SqlClient.SqlConnection;
conn.AccessToken = await (new AzureServiceTokenProvider()).GetAccessTokenAsync("https://database.windows.net/");
return da;
} catch (Exception ex) {
_log.LogError(ex);
throw;
}
}
Но это все еще оставляет меня с проблемой, что в конструкторе контроллера я не могу вызвать асинхронную фабричную функциюне заставляя его работать синхронно. В любом случае, я могу установить это свойство асинхронно?