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接口相反。您也可以从中受益,因为它使添加对其他图像服务的支持变得更容易。