模型继承 - 使用IoC的存储库模式

时间:2013-06-04 07:40:53

标签: c# design-patterns repository inversion-of-control

我是IoC和Repository Pattern的新手。我能够做一些测试项目,它的工作原理。但是,我不太确定我实施的是一个好的做法。我创建的测试项目包含所有存储库以及带有虚拟数据的工作接口。但我想要的是我的项目不应该知道我的模型的具体类型,因为初始版本应该使用MSSQL实现,第二个版本将是MSSQL和NoSQL的混合(用于读取和日志记录)。这些模型可能具有不同的属性或结构,从MSSQL到NoSQL(或将来可能使用的任何东西)

所以我尝试为每个模型创建一个界面:

public interface ISearchResult
{
    string Id { get; set; }
    string Name { get; set; }
    string Description { get; set; }
    string Url { get; set; }
}

这是存储库:

public interface ISearchRepository<T> where T: class, ISearchResult
{
    IEnumerable<T> Search<T>(string keyword, IEnumerable<string> regions, IEnumerable<string> industries,IEnumerable<string> countries, IEnumerable<string> cities, int offset);
}

这是服务:

public interface ISearchService
{
    IEnumerable<T> Search<T>(string keyword, IEnumerable<string> regions, IEnumerable<string> industries,IEnumerable<string> countries, IEnumerable<string> cities, int offset);
}

因为即使没有MSSQL或NoSQL实体我想拥有一个可用的GUI,我创建了一个继承了ISearchResult的View Model:

public class SearchResultViewModel : ISearchResult
{
    [Display(Name="Reference Id")]
    public string Id { get; set; }
    [Display(Name = "Company")]
    public string Name { get; set; }
    [Display(Name = "Description")]
    public string Description { get; set; }
    [Display(Name = "Website")]
    public string Url { get; set; }
}

这是它在我的控制器上的样子:

[SearchQueryFilter]
[GeoTargetFilter]
public ActionResult Query(SearchQueryModel searchQuery)
{
     searchQuery.Results = this._searchService.Search<SearchResultViewModel>(searchQuery.Keyword,searchQuery.Region, new List<string>() { searchQuery.Industries }, new List<string>() { searchQuery.Countries}, new List<string>() {searchQuery.City}, searchQuery.Offset)
            .ToList<ISearchResult>();

        return View(searchQuery);
 }

我的观点看起来像这样:

@foreach (SearchResultViewModel result in Model.Results)
{
     //code to display
}

我的问题是:使用这种方法可以吗?我不希望我的Web应用程序依赖于我的数据实体,这就是为什么我想让我的视图模型继承一个接口。因为我是IoC和Repository Pattern的新手并且只有一个测试项目,所以我不知道从长远来看,我的解决方案是否会成为一个问题。

任何建议都非常感谢。

1 个答案:

答案 0 :(得分:2)

您不需要在视图模型中实现接口,以便在Web应用程序和数据实体之间创建分离。您的视图模型应属于到您的Web应用程序,并且本身应独立于您的数据实体。

所以,而不是:

_searchService.Search<SearchResultViewModel>(x);

你应该在你的控制器中:

var result = _searchService.Search<SomeEntity>(x);
var model = new SearchResultsViewModel
{
    Name = result.Name,
    Desc = result.Desc,
    Url = result.Url
};
return View(model);

视图模型属于Web应用程序,负责包含从控制器传递到视图(和返回)的数据 - 它应该与您的服务层(或您的应用程序的任何其他层)无关。

SomeEntity是一个具体的类,以您的搜索服务公开的形式出现。您的控制器将以与任何其他应用程序相同的方式使用它,然后编译视图模型以传递到视图和从视图传递。您甚至可能会发现SomeEntity最初与SearchResultsViewModel或多或少相同;但是,它们仍然是不同的实体,因为视图的要求可能会独立于搜索服务而变化。