2013-01-24 38 views
4

我一直在试图找到一种通过“视图”暴露对象的灵活方式。举例来说,我可能更好解释。通过“视图”界面暴露对象

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

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

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

-

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

然而,为了做这样的事情,我必须有我的实体实现视图接口。我希望有更灵活的“鸭式”方法,因为可能会有很多对象的观点,我并不是真的想要全部实现它们。

我已经通过反射接口并复制字段和属性来构建动态类型,但我无法将其转换回接口类型,以便在Web服务上获得强大的输入。

只是寻找一些意见和建议,都会受到欢迎。谢谢。

+0

为什么不使用[数据合同](http://msdn.microsoft.com/zh-cn/library/ms733127.aspx)? –

+0

@Barguast:铸造应该非常简单,因为您的类型是泛型类型参数。也许你可以扩展你的问题到底是什么 –

+0

你将不得不定义哪些属性要包含哪些属性,哪些属性可以省略,也许有些类型转换。这可以通过很多方式完成,但明确的POCO/DTO或标记具有属性的实体似乎是最直接的选择。这不可能通过魔法发生。 – Jodrell

回答

3

您不应该直接将实体直接传递给客户端,而只应将其用于持久性。您应该引入DTOs/POCOs为您的API想要返回的任何数据量身定制,例如

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); 
} 
+0

我同意AutoMapper或类似的东西可以帮助删除一些枯燥乏味的东西,但是,它并不适合手工创建和维护。手动方法确实提供了最大的灵活性。 – Jodrell

+0

@Jodrell是的,但是,我同意,如果你发现自己到处都是这样,甚至只是试图映射具有许多属性的对象,那么AutoMapper(等等)的真正好处就来了。 – James

+0

谢谢, m用来做DTO的方式,我经常发现自己需要同一个实体的各种表示。例如,某些客户可能需要该人员的姓名。其他人可能还需要出生日期。其他人可能还需要该人属于的公司或同事名单等。这些实际上是对同一实体的所有不同“观点”,我希望能够将此视图定义为结构 - 暗示接口比为每个场景创建一个DTO。 – Barguast

1

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

作为一个侧面说明,共享ID和其他参考的数据将是必要的,如果你想更新的数据,因为你需要知道,为了知道哪个结果来更新密钥。

+0

我同意AutoMapper或类似的东西可以帮助删除一些乏味,但它不是擅自手工完成的。手动方法确实提供了最大的灵活性。 – Jodrell

+0

我会看看这个工具,看看它是否会帮助我。谢谢。 – Barguast