用抽象类型实现抽象类
本文关键字:抽象类 实现 类型 抽象 | 更新日期: 2023-09-27 18:12:44
我有一个基抽象类,它接受来自抽象类的类型,我正在努力弄清楚如何正确地实现它。
基类:
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接口,其中很明显您传递了TRequest
并接收了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)负责初始化。
我在c# 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)
如果有帮助,请标记为答案!