2009-02-09 100 views
2

正如我之前说过的,我正在开发一个digg克隆来教自己ASP.NET MVC内部和外部,但我碰到了一个我似乎无法避免的道路碰撞。ASP.NET MVC设计

我希望能够尽可能地优化这个应用程序,所以我有我的DAL这是一堆的类... Repository:Repository。现在为了优化性能,我有我的基础存储库类返回我的ViewData对象,以便他们可以选择所需的额外字段而不必创建匿名类型。

故事有创建它们的用户和用户有故事投票。非常容易的DB布局。现在我处理自己的成员资格,因为默认的ASP.NET成员资格非常臃肿。在我看来的故事列表中,我必须确定当前用户是否对所呈现的故事进行了投票。现在,因为我认为View中的数据访问不应该发生,它应该在我的控制器或DAL中。因为我已经从我的DAL返回ViewData,所以在名为“UserVotedOn”的StoryViewData类型上添加了另一个属性,如果用户对该故事进行了投票,则返回true。

问题在于我必须A)让DAL知道成员资格或B)将用户ID传递到DAL上的查询方法中。这些都不适合我,我正在寻找一些好的解决方案。欢迎任何反馈。

回答

3

在我的MVC应用程序中,我使用的是Rob Conery在MVC店面视频系列中展示的架构,它对我来说就像魅力一样。

库=>服务+过滤器=>控制器=>查看

我试图模仿要达到什么和管理待办事项这样

EDIT1:在库中改变的IList IQueryable的到和过滤器

public interface IRepository 
{ 
    IQueryable<Vote> GetVotes(); 
    IQueryable<Story> GetStories(); 
} 

服务为得到你想要的

public class Service : IService 
{ 
    private IRepository _repository; 

    public Service(IRepository repository) 
    { 
     _repository = repository; 
     if (_repository == null) throw new InvalidOperationException("Repository cannot be null"); 
    } 
    public IList<Vote> GetUserVotes(int userID) 
    { 
     return _repository.GetVotes().WithUserID(userID).ToList(); 
    } 
    public IList<Story> GetNotVotedStories(IList<Vote> votes) 
    { 
     return _repository.GetStories().WithoutVotes(votes).ToList(); 
    } 
} 

过滤器来过滤你的故事和用户投票(这些基本上是扩展方法)。不是最好的实施摆在那里,但你以后可以改写

public static class Filters 
{ 
    public static IQueryable<Vote> WithUserID(this IQueryable <Vote> qry, int userID) 
    { 
     return from c in qry 
       where c.UserID == userID 
       select c; 
    } 
    public static IQueryable<Story> WithoutVotes(this IQueryable <Story> qry, IList <Vote> votes) 
    { 
     return from c in qry 
       where votes.Where(x => x.StoryID == c.StoryID).ToList().Count > 0 
       select c; 
    } 
} 

然后你就可以在控制器通过当前用户名,而不是在DAL或视图像你不得不这样做之前

public class HomeController : Controller 
{ 
    private readonly IRepository _repository; 
    private readonly IService _service; 

    public HomeController() 
    { 
     _repository = new Repository(); 
     _service = new Service.Service(_repository); 
    } 

    public ActionResult Index() 
    { 
     var userVotes = _service.GetUserVotes(CurrentUserID); 
     var unvotedStories = _service.GetNotVotedStories(userVotes); 

     return View(unvotedStories); 
    } 
} 

这可以让你以避免添加用户相关UserVotedOn属性到您的故事模型

1

看起来你错过了BLL。实际上,MVC应用程序的正确架构是许多人仍在试图弄清楚的。

我个人认为UserID有点像是跨平台的概念。它将出现在DAL和BLL两个层面上。

基本上,您的控制器方法应该只对BLL进行一些非常基本的调用,仅用于确定如何对用户输入做出反应,无论是返回视图还是其他视图。

您的视图应该只处理模型对象。模型应该可能由业务逻辑填充。您可以在控制器方法中调用BL方法以初始化您的模型对象,然后将其传递给视图。

控制器不应直接与数据库通信。它也不应该处理组成你的域对象和模型的低级对象。

P.S.我会尽量避免广泛使用ViewData。强类型模型类是一个更好的选择。您也可以将它们按层次结构分组,以继承一些常用属性。就像您的域模型类可以从具有UserID属性定义的基类派生一样。

+0

那么,当我说DAL技术上是一个BLL。它包装了datacontext。当我说ViewData我的意思是我有ViewData类,我传递到强类型的意见。感谢您的输入,我会把它浸入其中。 – 2009-02-09 18:41:01

+0

我自己一直在试图想出“完美”的MVC架构。经过几个月的试验后,我可以说完美的架构和理想的关注分离是不可能的(谁会怀疑)。你只需要认同你自己并做出一些妥协。 – User 2009-02-09 18:49:26