2013-01-24 137 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