我的问题是...
...我有这样的 DTO
[Route("/route/to/dto/{Id}", "GET")]
public class Foo : IReturn<Bar>
{
public string Id { get; set; }
}
并且需要使用此签名调用实现该方法的服务
public Bar Get(Foo)
来自请求和/或响应过滤器。我不知道哪个类实现了它(不想知道)。我需要的是类似于下面示例中的 LocalServiceClient 类:
var client = new LocalServiceClient();
Bar bar = client.Get(new Foo());
这个 LocalServiceClient 东西存在吗?JsonServiceClient 有一个非常相似的接口,但是使用它是无用的(我需要调用我自己的服务,我不应该需要额外的往返,甚至到本地主机,只是为了做到这一点)。
我知道来自 Service 类的 ResolveService 方法,但它要求我有一个服务实例并知道哪个类将处理请求。
我认为这个 LocalServiceClient 是可能的,因为我拥有远程客户端(例如 JsonServiceClient)调用服务所需的所有数据——请求 DTO、路由、动词——但找不到如何去做。实际上,它应该比 JsonServiceClient 更容易实现。
JsonServiceClient 会这样做,但必须有更好的方法,使用相同的请求上下文。
我想做什么(如果你不好奇我为什么这样做,请跳过这个)
实际上,我的 DTO 是这样的:
[EmbedRequestedLinks]
[Route("/route/to/dto/{Id}", "GET")]
public class MyResponseDto
{
public string Id { get; set; }
public EmbeddableLink<AResponseDto> RelatedResource { get; set; }
public EmbeddableLink<AnotherResponteDto> AnotherRelatedResource { get; set; }
}
EmbedRequestedLinksAttribute 是一个请求/响应过滤器。此过滤器检查请求中是否存在名为“embed”的查询参数。如果是这样,过滤器需要将参数引用的逗号分隔的相关资源“嵌入”到对该请求的响应中。EmbeddableLink<T> 实例可以通过使用如下扩展方法获得:
1) public static EmbeddableLink<T> ToEmbeddableLink<T>(this IReturn<T> requestDto)
2) public static EmbeddableLink<T> ToEmbeddableLink<T>(this T resource)
假设客户端发出此请求:
GET /route/to/dto/123456?embed=relatedResource HTTP/1.1
将处理此请求的服务将返回 MyResponseDto 的实例,其中包含使用签名 (1) 创建的 EmbeddableLinks。然后我的响应过滤器将看到嵌入查询参数,并将调用相应服务的 Get 方法,将 RelatedResource 替换为 EmbeddableLink 的另一个实例,这次使用扩展方法 (2) 创建:
var client = new LocalServiceClient();
response.RelatedResource = client.Get(response.RelatedResource.RequestDto)
.ToEmbeddableLink();
EmbeddableLink 的序列化例程负责其余的工作。
如果嵌入列表中不包含可嵌入链接,则序列化例程将调用扩展方法 ToUrl(由 ServiceStack 提供),该方法采用动词并将请求 DTO 转换为 URL。在此示例中,客户端将收到以下响应:
{
"id": "9asc09dcd80a98",
"relatedResource": { "id": "ioijo0909801", ... },
"anotherRelatedResource":
{
"$link": { "href": "/route/to/another/dto/1sdf89879s" }
}
}
我知道 ServiceStack 的创建者认为多态请求/响应是坏事,但这种情况对我来说似乎没问题,因为我不是在创建服务,而是在扩展框架以帮助我以我(可能还有其他用户)的方式创建服务ServiceStack) 需要。我还在为 ServiceStack 创建其他超媒体扩展。(希望老板允许我在github上发布这些扩展)