2

在ASP.NET MVC中使用Ninject時,抽象出第三方依賴關係的最佳方式是什麼?如何處理抽象第三方依賴項(依賴注入)?

通常情況下,我做這樣的事情:

public interface IProductRepository 
{ 
    IEnumerable<Product> GetProducts(); 
} 

public class ProductRespository : IProductRepository 
{ 
    public IEnumerable<Product> GetProducts() 
    { 
     ... 
    } 
} 

然後在控制器:

public class ProductController : Controller 
{ 
    private IProductRepository repository; 

    public ProductController(IProductRepository repository) 
    { 
     this.repository = repository; 
    } 

    ... 
} 

然後我用Ninject自動注入固體ProductRepository到控制器。

但是,如果依賴項是第三方,我該如何做到這一點?例如,我正在使用FlickrNet

public class ProductController : Controller 
{ 
    private Flickr flickr; 

    ... 
} 

我希望能夠抽象Flickr對象擄到一個接口,這樣我可以使用依賴注入並使其更容易進行單元測試。我知道我可以創建一個'服務'類型的接口,然後根據將包裝Flickr對象的類實現一個類。

但我必須在對應於Flickr對象的每個成員的接口中定義一個成員,然後將這些成員映射到包裝器對象中。 Flickr對象中有許多成員。

有沒有更好的方法來處理這個問題?我的主要目標是在單元測試中輕鬆模擬Flickr依賴。

+0

Flicker對象中的方法是否是偶然虛擬的? – 2012-08-09 01:48:07

+0

@BrianDishaw不,他們不是。 – 2012-08-09 01:55:14

+1

我想這太容易了。似乎你必須包裝它,並創建一個界面..也許有代碼生成器,可以爲你寫鍋爐板? – 2012-08-09 01:58:57

回答

3

將我的評論升級爲答案。

這不是DI的問題,而是一般的體系結構問題。您可以將控制器聲明爲抽象層,也可以定義實現自定義接口的flickr組件的包裝器。如果你的第三方組件上的方法消耗更多的第三方類,那麼你需要將它們抽象出來,等等,直到你只有原始值或更多的第三方代碼包裝器。根據組件的複雜性,這可能意味着很多映射和包裝。

2

我認爲一個包裝是正確的路要走。你不必公開第三方對象的每一個成員 - 只需要你需要的成員。對於不同情況的不同界面,包裝解決方案變得更加漂亮。

1

唯一的目的是將flickr .NET抽象爲更高層的抽象層。例如

interface IAlbumViewer 
{ 
    IEnumerable<IImage> GetImages(); 
} 

interface IPictureUploader 
{ 
    string Upload(string filename, Stream image) 
} 

也就是說,創建特定於您的用例的接口/方法與通用flickr接口相反。您也可以從中受益,因爲它使添加對其他圖像服務的支持變得更容易。