gpt4 book ai didi

servicestack - ServiceStack 是否支持端到端类型化请求中的泛型

转载 作者:行者123 更新时间:2023-12-04 04:41:28 30 4
gpt4 key购买 nike

我在玩 ServiceStack,想知道它是否支持这种情况。我在我的请求类型中使用了泛型,这样许多从公共(public)接口(interface)继承的 DTO 将支持相同的基本方法 [比如... GetById(int Id)]。

使用特定于一种 DTO 的请求类型是可行的,但会破坏泛型的优点...

var fetchedPerson = client.Get<PersonDto>(new PersonDtoGetById() { Id = person.Id });
Assert.That(person.Id, Is.EqualTo(fetchedPerson.Id)); //PASS

将路由映射到泛型也有效:

Routes.Add<DtoGetById<PersonDto>>("/persons/{Id}", ApplyTo.Get);
...
var fetchedPerson2 = client.Get<PersonDto>(string.Format("/persons/{0}", person.Id));
Assert.That(person.Id, Is.EqualTo(fetchedPerson2.Id)); //PASS

但是使用端到端的通用请求类型失败了:

var fetchedPerson3 = client.Get<PersonDto>(new DtoGetById<PersonDto>() { Id = person.Id });
Assert.That(person.Id, Is.EqualTo(fetchedPerson3.Id)); //FAIL

我想知道我是否只是遗漏了什么,或者我是否试图抽象太过分的一层... :)

下面是一个完整的、失败的程序,使用 NUnit,默认的 ServiceStack 东西:

namespace ssgenerics
{
using NUnit.Framework;
using ServiceStack.ServiceClient.Web;
using ServiceStack.ServiceHost;
using ServiceStack.ServiceInterface;
using ServiceStack.WebHost.Endpoints;

[TestFixture]
class Program
{
public static PersonDto GetNewTestPersonDto()
{
return new PersonDto()
{
Id = 123,
Name = "Joe Blow",
Occupation = "Software Developer"
};
}

static void Main(string[] args)
{}

[Test]
public void TestPutGet()
{
var listeningOn = "http://*:1337/";
var appHost = new AppHost();
appHost.Init();
appHost.Start(listeningOn);
try
{

var BaseUri = "http://localhost:1337/";
var client = new JsvServiceClient(BaseUri);

var person = GetNewTestPersonDto();
client.Put(person);

var fetchedPerson = client.Get<PersonDto>(new PersonDtoGetById() { Id = person.Id });
Assert.That(person.Id, Is.EqualTo(fetchedPerson.Id));

var fetchedPerson2 = client.Get<PersonDto>(string.Format("/persons/{0}", person.Id));
Assert.That(person.Id, Is.EqualTo(fetchedPerson2.Id));
Assert.That(person.Name, Is.EqualTo(fetchedPerson2.Name));
Assert.That(person.Occupation, Is.EqualTo(fetchedPerson2.Occupation));

var fetchedPerson3 = client.Get<PersonDto>(new DtoGetById<PersonDto>() { Id = person.Id });
Assert.That(person.Id, Is.EqualTo(fetchedPerson3.Id));
Assert.That(person.Name, Is.EqualTo(fetchedPerson3.Name));
Assert.That(person.Occupation, Is.EqualTo(fetchedPerson3.Occupation));
}
finally
{
appHost.Stop();
}
}
}

public interface IDto : IReturnVoid
{
int Id { get; set; }
}

public class PersonDto : IDto
{
public int Id { get; set; }
public string Name { get; set; }
public string Occupation { get; set; }
}

public class DtoGetById<T> : IReturn<T> where T : IDto { public int Id { get; set; } }
public class PersonDtoGetById : IReturn<PersonDto> { public int Id { get; set; } }

public abstract class DtoService<T> : Service where T : IDto
{
public abstract T Get(DtoGetById<T> Id);
public abstract void Put(T putter);
}

public class PersonService : DtoService<PersonDto>
{
public override PersonDto Get(DtoGetById<PersonDto> Id)
{
//--would retrieve from data persistence layer
return Program.GetNewTestPersonDto();
}

public PersonDto Get(PersonDtoGetById Id)
{
return Program.GetNewTestPersonDto();
}

public override void Put(PersonDto putter)
{
//--would persist to data persistence layer
}
}

public class AppHost : AppHostHttpListenerBase
{
public AppHost()
: base("Test HttpListener",
typeof(PersonService).Assembly
) { }

public override void Configure(Funq.Container container)
{
Routes.Add<DtoGetById<PersonDto>>("/persons/{Id}", ApplyTo.Get);
}
}
}

最佳答案

不,这是 ServiceStack 中的一个基本概念,即每个服务都需要自己的唯一请求 DTO,请参阅 this answer for more examples on this .

你可以这样做:

[Route("/persons/{Id}", "GET")]
public class Persons : DtoGetById<Person> { ... }

但我强烈advise against using inheritance in DTOs .属性声明就像服务契约(Contract)的 DSL,它不是应该隐藏的东西。

有关详细信息,请参阅此答案 on the purpose of DTO's in Services .

关于servicestack - ServiceStack 是否支持端到端类型化请求中的泛型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15934722/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com