在构造函数中异步设置控制器属性

时间:2019-10-03 14:12:36

标签: c# asynchronous dependency-injection async-await

我有一个 完全异步 MVC API,该接口将接口插入其所有控制器:

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;
    }
}

但是,这仍然给我带来了一个问题,即在控制器构造函数中,如果不强制其异步运行,则无法调用异步工厂函数。无论如何,我可以异步设置此属性吗?

1 个答案:

答案 0 :(得分:0)

当我需要类似的东西时,我使用了工厂模式,但有两个关键方面:

  1. 在类本身中将工厂方法设为静态方法,因为这使您可以访问fetchCryptoToCurrencyBegin()属性和方法。
  2. 将构造函数标记为SELECT * FROM BM_BNKA_FLATFILE_FEDACHDIR2018_ZIP_5_010 EXCEPT ( SELECT SWIFT_US.BIC, FED_ACH_5ZIP.RoutingNumber, FED_ACH_5ZIP.BankName, FED_ACH_5ZIP.BankCity, FED_ACH_5ZIP.BankStateCd, FED_ACH_5ZIP.BankZip_5, FROM dbo.BM_BNKA_FLATFILE_FEDACHDIR2018_ZIP_5_010 AS FED_ACH_5ZIP LEFT OUTER JOIN dbo.BM_BNKA_FLATFILE_SWIFT_US_LPAD_SMALLZIP_SPLIT_CITY_STATE AS SWIFT_US ON FED_ACH_5ZIP.BankName = SWIFT_US.INSTITUTION_NAME AND FED_ACH_5ZIP.BankCity = SWIFT_US.CITYNEW AND FED_ACH_5ZIP.BankStateCd = SWIFT_US.STATENEW /*AND FED_ACH_5ZIP.BankZip_5 = SWIFT_US.ZIPNEW */ WHERE (SWIFT_US.BIC IS NOT NULL) AND FED_ACH_5ZIP.RoutingNumber NOT IN (SELECT RoutingNumber FROM BM_BNKA_FLATFILE_FEDACHDIR2018_NDIST_BIC_ZIP_5_030) UNION ALL SELECT * FROM BM_BNKA_FLATFILE_FEDACHDIR2018_NDIST_BIC_ZIP_5_030 ) ,以便没有使用工厂方法的任何人都不能使用该类。

对于您来说,它看起来像这样:

private