簡體   English   中英

我的Web Api Rest客戶端強迫我引用實體框架

[英]My Web Api Rest client is forcing me to reference Entity Framework

我有一個MVC Api端點,並且我也在創建一個api rest客戶端項目,該項目還包裝了api端點服務。

我正在使用實體框架,首先進行編碼。

我的Web API項目如下所示:

project-mvc
project-core  (this contains entity framework, models, etc.)

現在,當我創建我的rest api客戶端項目時:

project-api-client

問題是,我必須引用項目核心,因為它包含模型,但是由於它是依賴項,因此我還獲得了實體框架。

因此,我嘗試創建一個單獨的模型項目:

project-models

但是似乎仍然必須引用EntityFramework,否則我的屬性似乎不起作用,例如:

public class Something
{

        [Key]
        [Column("Something_ID")]
        public int Id { get; set; }

    ....
}

我以為您所需要的只是使用System.ComponentModel.DataAnnotations,但我被迫引入EntityFramwork。

我做錯了嗎?

聽起來您需要解耦圖層; 通常,將EF對象傳遞到周圍,更具體地說,是將它們從控制器通過電線扔掉是一個壞主意,因為您最終可能會暴露出數據模型中客戶不感興趣(或不感興趣)的部分。

糾正此問題的一種方法如下(注意:此示例是即時進行的,並不是嚴格地說是“最佳”或最不相關的正確方法,但我想向您推薦正確的方向

接口您需要做的是定義一個接口,該接口描述客戶端可能希望看到的MyThing的重要屬性。 您可以將此接口定義放在一個單獨的項目中(假設為“ MyInterfaces”),並從您的EF項目中引用該項目:

public interface IThing
{
   int ID{get;set;}
   string Data{get;set;}
}

使用數據傳輸對象時,可以在Interfaces項目中創建IThing的具體實現數據傳輸對象:

public class MyThingDTO:IThing
{
   public int ID{get;set;}
   public string Data{get;set;}
}

注意:嚴格來說,應在項目的各個“層”中重新實現此模型,而interfaces項目應僅包含接口,但為簡單起見,我在所有層中都使用相同的DTO。

實體現在您可以在EF項目中定義一個實體,如下所示

public class MyThing:IThing
{
   [Key]
   [Column("MyThing_ID")
   public int ID{get;set;}
   [Column("MyThing_Data")
   public string Data {Get;set;}
}

數據訪問層現在,您可以創建一個數據訪問層項目,該項目引用您的Entity Framework和Interface項目,並創建某種類,該類的工作是為IThings的請求提供服務。

public class MyThingDataService
{
   public IThing GetByID(int ID)
   {
      //EF code to query your database goes here, assuming you have a valid DBContext called "ctx". I won't go into how you might create or inject this, etc, as it's a separate topic e.g Dependency Injection.
     var thing = ctx.MyThings.FirstOrDefault();
     if (thing!=null)
    {
        return new MyThingDTO{ID=thing.ID, Data=thing.Data};
    }
    else{//handle the not found case here}
   }
}

參考最后,您從MVC項目中引用了“數據訪問層和接口”項目,控制器代碼現在看起來像

public MyThing Get(int id)
{
   //assuming you have an instance of MyThingDataService here, injected via DI or manually created, etc.
//strictly speaking we should declare our controller return type as IMyThing 
//but this means we have to also decorate the DTO class with some attributes for the serialiser     
//(KnownType) and I don't want to confuse things, hence the cast.
   return dataService.GetByID(id) as MyThing; 
}

現在,對EF項目的唯一引用是在Central Interfaces項目中。

您的客戶端項目僅需要引用Interfaces項目(實際上,您實際上並不需要這樣做,因為您的客戶端通過HTTP接收序列化數據,因此可以自由地在IMyThing接口上實現自己的功能,但是重新進行操作非常方便僅用於節省時間)。

包起來

我提到這只是朝正確方向的推動力-要實現真正分離的實現,您需要做更多的工作。 -您的數據訪問層也應按接口定義,並且應使用某種DI容器將其注入到MVC控制器中; -您的Interfaces項目應該只包含接口,並且每一層都應實現自己的具體類以表示流經它的數據(即,它們都應具有自己的MyThingDTO實現IMyThing的風格)-執行此操作時,您將看到一個很好解耦的系統,因為所有層(MVC,數據訪問,EF)都沒有相互引用,而僅涉及集中式接口項目。 -也許比我聰明的人會發現您需要做的其他事情,因為我可能已經忘記了一些-現在還很早(遲到嗎?)。

無論如何。 希望這可以幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM