簡體   English   中英

用抽象類型實現抽象類

[英]Implementing abstract class with abstract types

我有一個基礎抽象類,它接受來自抽象類的類型,我正用頭撞牆,試圖找出如何正確實現它。

基類:

public abstract class ApiService<TRequest, TResponse>
    where TRequest : ApiRequest
    where TResponse : ApiResponse
{
    public abstract TResponse Execute(TRequest Request);
}

ApiRequest 類:

public abstract class ApiRequest
{

}

ApiResponse 類:

public abstract class ApiResponse
{
    public bool Succeeded { get; set; }

}

我創建了一個 TestService 類來嘗試解決這個問題,但這些概念對我來說並沒有結合在一起:

public class TestService : ApiService<ApiRequest, ApiResponse>
{
    public override ApiResponse Execute(ApiRequest Request)
    {
        ApiResponse response;

        return (response);
    }

您能提供的任何幫助將不勝感激,並幫助我進一步了解抽象類! 謝謝!

所以我的問題是:我不知道如何在 Execute 方法中實現 ApiResponse,因為您無法實例化抽象類。

泛型和多態化很好,但它必須在某個時候停止。 在您的情況下,您有一個很好的 API 接口,很明顯您傳遞了一個TRequestTResponse接收了一個TResponse

您應該添加的是如何對待特定情況。 添加一層IRequestHander<TRequest,TResult> ,它將知道如何從特定的Request創建特定的Result

然后使用Factory設計模式,您的 API 函數將調用工廠以獲取適合其獲得的請求的特定處理程序。 它將執行RequestHander並返回它從中獲得的Response

public class SpecificRequestA : ApiRequest {}
public class SpecificResponseA : ApiResponse{}

public interface IRequestHander<TRequest,TResponse>
    where TRequest : ApiRequest
    where TResponse : ApiResponse
{
    TResponse Exeute(TRequest request);
}

public class SpecificRequestHandlerA : IRequestHander<SpecificRequestA,SpecificResponseA>
{
    SpecificResponseA Execute(SpecificRequestA request)
    {
        //create the new response out of the given request. Here you know exactly on what you are working :)
    }
}

然后添加工廠。

還可以考慮將請求實現為Request<TResponse> - 看看它是否更適合您的情況

我建議研究依賴注入和 DI 容器(如 Castle、Ninject、Unity、Simple Injector)來負責初始化。

我在 ac# MVC UI 層中使用了以下 ApiClient 類:

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using System.Web;
using System.Web.Helpers;
using System.Web.Mvc;

namespace DocumentManager.UI
{
    public class ApiClient<T>
    {
        public ApiClientErrorTypes Error{get;private set;}

        private string baseUri =  @"http://localhost/DocumentManager.WebAPI/";

        public T ApiGet(string requestUrl)
        {
            using (var client = new HttpClient())
            {
                var requestUri = new Uri(baseUri + requestUrl);
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                if (ApiAuthToken.token != null)
                {
                    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", ApiAuthToken.token.ToString());
                }
                var response = client.GetAsync(requestUri).Result;
                string contentString = response.Content.ReadAsStringAsync().Result;
                if (response.IsSuccessStatusCode)
                {
                    T result = JsonConvert.DeserializeObject<T>(contentString);
                    return result;
                }
                if (int.Parse(response.StatusCode.ToString()) > 400 && int.Parse(response.StatusCode.ToString()) <= 499)
                    Error = ApiClientErrorTypes.UnAuthorised;
                else
                    Error = ApiClientErrorTypes.Technical;
                return default(T);
            }
        }

        public T ApiPost(string requestUrl, HttpContent encodedContent)
        {
            using(var client = new HttpClient())
            {
                var requestUri = new Uri(baseUri + requestUrl);
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                if (ApiAuthToken.token != null)
                {
                    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", ApiAuthToken.token.ToString());
                }
                var response = client.PostAsync(requestUri, encodedContent).Result;
                string contentString = response.Content.ReadAsStringAsync().Result;
                if (response.IsSuccessStatusCode)
                {
                    T result = JsonConvert.DeserializeObject<T>(contentString);
                    return result;
                }
                if (int.Parse(response.StatusCode.ToString()) > 400 && int.Parse(response.StatusCode.ToString()) <= 499)
                    Error = ApiClientErrorTypes.UnAuthorised;
                else
                    Error = ApiClientErrorTypes.Technical;
                return default(T);
            }
        }

        public bool ApiPostBool(string requestUrl, HttpContent encodedContent)
        {
            using (var client = new HttpClient())
            {
                var requestUri = new Uri(baseUri + requestUrl);
                client.DefaultRequestHeaders.Accept.Clear();
                client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
                if (ApiAuthToken.token != null)
                {
                    client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", ApiAuthToken.token.ToString());
                }
                var response = client.PostAsync(requestUri, encodedContent).Result;
                string contentString = response.Content.ReadAsStringAsync().Result;
                if (response.IsSuccessStatusCode)
                {
                    return true;
                }
                return false;
            }
        }
    }
}

我從 MVC 控制器以下列方式調用它:

var apiClient = new ApiClient<Document>();
var doc = apiClient.ApiGet("api/document/get/" + id);
if (doc != null)
{
    //do stuff here
}

我使用以下 Web API 層方法返回此項目

namespace DocumentManager.WebApi.Controllers
{
    [RoutePrefix("api/document")]
    public class DocumentController : BaseController
    {
        [Route("get/{id}")]
        public IHttpActionResult Get(int id)
        {
            return Ok(DACDocument.Read(new DataContext(),id));
        }
    }
}

這背后有一個實體框架數據層(DAC ...)

我使用這種架構結構的原因是我希望多個 MVC UI 前端應用程序綁定到 API 后端。

解決方案中的項目是數據(類庫)API(Web API)UI(Web MVC)

如果這有幫助,請標記為答案!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM