通过“视图”界面公开对象

本文关键字:对象 界面 视图 通过 | 更新日期: 2023-09-27 17:56:04

我一直在尝试找到一种通过"视图"公开对象的灵活方法。我最好通过示例来解释。

我有一个实体框架实体模型和一个可用于查询它的 Web 服务。我可以返回实体类本身,但这将包括一些我可能不想共享的字段 - 例如 ID,或 *引用实体模型中任何关联的属性。

我认为我需要的是数据视图,但我并不特别想为每个返回类型编写一个视图包装类。我希望我能够定义一个接口并以某种方式使用它。例如:

interface IPersonView
{
     string FirstName { get; }
     string LastName { get; }
}

-

// (Web service method)
IPersonView GetPerson(int id)
{
    var personEntity = [...];
    return GetView<IPersonView>(personEntity);
}

但是,为了执行此类操作,我必须让我的实体实现视图接口。我希望有一种更灵活的"鸭子类型"方法,因为一个对象可能有很多视图,我真的不想全部实现它们。

我通过反映接口并复制字段和属性来构建动态类型取得了一些成功,但我无法将其转换回接口类型,以便在 Web 服务上获得强类型。

只是寻找一些意见和建议,两者都是受欢迎的。谢谢。

通过“视图”界面公开对象

你不应该真的将实体直接传递给客户端,它们应该仅用于持久性。您应该引入针对您的 API 想要返回的任何数据量身定制的 DTO/POCO,例如

public class PersonDto
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}
// public API method
public PersonDto GetPersonApi(int id)
{
    var personEntity = // pull entity from db
    return new PersonDto()
    {
        FirstName = personEntity.FirstName,
        LastName = personEntity.LastName
    };
}

这样可以在持久性层和公共接口之间保持清晰的分离。您可以使用像AutoMapper这样的工具来映射数据。只需设置一次映射,例如在您的全局 asax 中:

protected void Application_Start()
{
    Mapper.CreateMap<Person, PersonDto>();
}
...
// public API method
public PersonDto GetPersonApi(int id)
{
    var personEntity = // pull entity from db
    return Mapper.Map<Person, PersonDto>(personEntity);
}

我通常看到使用AutoMapper或类似工具完成此操作。 它使相似类之间的映射变得更加简单。 您仍然需要创建Views(在MVC上下文中将是一个Model),但是只要您使用相同的字段名称,最繁琐的部分(映射)就会为您处理。

作为旁注,如果要更新数据,则必须共享 ID 和其他参考数据,因为您需要知道键才能知道要更新的记录。