代码之家  ›  专栏  ›  技术社区  ›  Trevor Daniel

运行时将值发送到Singleton

c#
  •  0
  • Trevor Daniel  · 技术社区  · 6 年前

    在Startup.cs中,我有:

    services.AddSingleton<IApiClient>(new ApiClient(Configuration.GetValue<string>("WebApiBaseAddress")));
    

    我有一个小客户:

    public class ApiClient : IApiClient
    {
        private readonly HttpClient _client;
        private readonly JsonMediaTypeFormatter _formatter;
    
        /// <summary>
        /// The ApiClient constructor.
        /// </summary>
        public ApiClient(string baseAddress)
        {
            _client = new HttpClient { BaseAddress = new Uri(baseAddress) };
            _client.DefaultRequestHeaders.Accept.Clear();
            _client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            //_client.DefaultRequestHeaders.Add("Authorization", "Bearer " + apiToken);
    
            _formatter = new JsonMediaTypeFormatter();
            _formatter.SerializerSettings.NullValueHandling = Newtonsoft.Json.NullValueHandling.Ignore;
        }
    
        /// <summary>
        /// Fetches the list of <see cref="TModel"/>. 
        /// </summary>
        /// <typeparam name="TModel">Model's type.</typeparam>
        /// <param name="path">The uri path.</param>
        /// <returns>List of <see cref="TModel"/>.</returns>
        public async Task<IList<TModel>> Get<TModel>(string path)
        {
            return await Get<TModel>(path, null);
        }
    
        public async Task<TModel> GetObject<TModel>(string path)
        {
            // todo : use parameters
            var response = await _client.GetStringAsync($"{path}");
            var result = JsonConvert.DeserializeObject<TModel>(response);
    
            return result;
        }
    
        /// <summary>
        /// Fetches the list of <see cref="TModel"/>. 
        /// </summary>
        /// <typeparam name="TModel">Model's type.</typeparam>
        /// <param name="path">The uri path.</param>
        /// <param name="parameters">The uri parameters.</param>
        /// <returns>The list of <see cref="TModel"/>.</returns>
        private async Task<IList<TModel>> Get<TModel>(string path, IDictionary<string, string> parameters)
        {
            // todo : use parameters
            var response = await _client.GetStringAsync($"{path}");
            var result = JsonConvert.DeserializeObject<IList<TModel>>(response);
    
            return result;
        }
    
        /// <summary>
        /// Fetches the <see cref="TModel"/>. 
        /// </summary>
        /// <typeparam name="TModel">Model's type.</typeparam>
        /// <param name="path">The uri path.</param>
        /// <param name="id">Unique identifier of the model.</param>
        /// <param name="afterPath">The uri path after id.</param>
        /// <returns>The <see cref="TModel"/> model.</returns>
        public async Task<TModel> Get<TModel>(string path, object id, string afterPath = null)
        {
            var response = await _client.GetStringAsync($"{path}/{id}{afterPath}");
            var result = JsonConvert.DeserializeObject<TModel>(response);
    
            return result;
        }
    
        /// <summary>
        /// Creates the <see cref="TModel"/> model.
        /// </summary>
        /// <typeparam name="TModel">Model's type.</typeparam>
        /// <param name="path">The uri path.</param>
        /// <param name="model">The model.</param>
        public async Task<HttpResponseMessage> Post<TModel>(string path, TModel model)
        {
            HttpContent content = new ObjectContent<TModel>(model, _formatter);
            return await _client.PostAsync($"{path}", content);
        }
    
        /// <summary>
        /// Updates the <see cref="TModel"/> model.
        /// </summary>
        /// <typeparam name="TModel">Model's type.</typeparam>
        /// <param name="path">The uri path.</param>
        /// <param name="id">Unique identifier of the model.</param>
        /// <param name="model">The model.</param>
        public async Task<HttpResponseMessage> Put<TModel>(string path, object id, TModel model)
        {
            HttpContent content = new ObjectContent<TModel>(model, _formatter);
            return await _client.PutAsync($"{path}/{id}", content);
        }
    
        /// <summary>
        /// Partially update the model
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <param name="path"></param>
        /// <param name="id"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        public async Task<HttpResponseMessage> Patch<TModel>(string path, object id, TModel model)
        {
            JsonPatchDocument patchDoc = new JsonPatchDocument();
    
            foreach (PropertyInfo propInfo in model.GetType().GetProperties())
            {
                var value = propInfo.GetValue(model);
                if (value == null) continue;
                patchDoc.Replace(propInfo.Name, value);
            }
    
            var serializedPatchItem = JsonConvert.SerializeObject(patchDoc);
    
            var method = new HttpMethod("PATCH");
            var request = new HttpRequestMessage(method, $"{path}/{id}")
            {
                Content = new StringContent(serializedPatchItem, System.Text.Encoding.Unicode, "application/json")
            };
    
            return await _client.SendAsync(request);
        }
    
        /// <summary>
        /// Deletes the model.
        /// </summary>
        /// <param name="path">The uri path.</param>
        /// <param name="id">Unique identifier of the model.</param>
        public async Task<HttpResponseMessage> Delete(string path, object id)
        {
            return await _client.DeleteAsync($"{path}/{id}");
        }
    }
    }
    

    我有一个APIClient接口:

    public interface IApiClient
    {
        /// <summary>
        /// Fetches the list of <see cref="TModel"/>. 
        /// </summary>
        /// <typeparam name="TModel">Model's type.</typeparam>
        /// <param name="path">The uri path.</param>
        /// <returns>List of <see cref="TModel"/>.</returns>
        Task<IList<TModel>> Get<TModel>(string path);
    
        //
        Task<TModel> GetObject<TModel>(string path);
    
        /// <summary>
        /// Fetches the <see cref="TModel"/>. 
        /// </summary>
        /// <typeparam name="TModel">Model's type.</typeparam>
        /// <param name="path">The uri path.</param>
        /// <param name="id">Unique identifier of the model.</param>
        /// <param name="afterPath">The uri path after id.</param>
        /// <returns>The <see cref="TModel"/> model.</returns>
        Task<TModel> Get<TModel>(string path, object id, string afterPath = null);
    
        /// <summary>
        /// Creates the <see cref="TModel"/> model.
        /// </summary>
        /// <typeparam name="TModel">Model's type.</typeparam>
        /// <param name="path">The uri path.</param>
        /// <param name="model">The model.</param>
        Task<HttpResponseMessage> Post<TModel>(string path, TModel model);
    
        /// <summary>
        /// Updates the <see cref="TModel"/> model.
        /// </summary>
        /// <typeparam name="TModel">Model's type.</typeparam>
        /// <param name="path">The uri path.</param>
        /// <param name="id">Unique identifier of the model.</param>
        /// <param name="model">The model.</param>
        Task<HttpResponseMessage> Put<TModel>(string path, object id, TModel model);
    
        /// <summary>
        /// Partially updates the model
        /// </summary>
        /// <typeparam name="TModel"></typeparam>
        /// <param name="path"></param>
        /// <param name="id"></param>
        /// <param name="model"></param>
        /// <returns></returns>
        Task<HttpResponseMessage> Patch<TModel>(string path, object id, TModel model);
    
        /// <summary>
        /// Deletes the model.
        /// </summary>
        /// <param name="path">The uri path.</param>
        /// <param name="id">Unique identifier of the model.</param>
        Task<HttpResponseMessage> Delete(string path, object id);
    }
    

    因此,现在在启动时创建一个APIClient,其中包含配置中的基址。

    我想在运行时将另一个名为ApiToken的值传递给APIClient,并在用户成功登录后将其添加为登录控制器的授权头。

    我将从Auth控制器返回的API令牌存储在:

    new Claim("Token", loggedInUser.ApiToken.ToString())
    

    我将APIClient改为:

    public ApiClient(string baseAddress, string apiToken)
    

    但当它在一开始就设置好时,我不清楚如何在用户登录后在运行时设置它。

    有人能给我指点一下吗?

    0 回复  |  直到 6 年前