ASP.NET MVC模式 [英] ASP.NET MVC Patterns

查看:155
本文介绍了ASP.NET MVC模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是相当新的MVC,但与它玩耍后(MVC 3 /剃刀),我上瘾了。

我有几个问题:

1)什么是最好的,或者最广泛使用的模式来开发MVC中的应用程序?存储库,国内长途,UOW?

2)我使用实体框架4,所以可能有些请解释给我或点我一个很好的来源,这将解释Repository模式瓦特/ EF4?不EF4发生的业务层和数据访问层?是否Repository模式,甚至提供好处?

3)此外,还有最后一个问题,能不能有人解释控制器,模型和视图之间的整个关系?我得到的基本知识,但也许更多的在使用它的正确方法深入一点。视图模型 - 说我有一个显示客户信息的编辑是一个视图,一个,我应该有一个视图模式和编辑模式,或可在其传递

4)的例子?

您的帮助感谢前面,结果
$(山姆)

**编辑**

我在正确的轨道上:

 公共类HomeController的
    继承System.Web.Mvc.Controller    功能指数(BYVAL编号为整数)作为的ActionResult
        返回查看(新HomeModel)
    结束功能    &所述; HttpPost()> _
    功能指数(BYVAL模型正如HomeModel)作为的ActionResult
        返回查看(型号)
    结束功能末级公共类HomeModel
    私人_repository作为IRepository(客户)的    公共财产客户为客户    的Public Sub New()    结束小组    的Public Sub New(BYVAL ID作为整数)
        _repository =新CustomerRepository
        顾客= _Repository.GetByID(ID)的
    结束小组末级公共接口IRepository(中T)
    功能GetByID(BYVAL ID作为整数)作为T形
    减少添加(BYVAL实体T)
    分删除(BYVAL实体T)结束接口公共类CustomerRepository
    实现IRepository(客户)的    公用Sub添加(BYVAL实体客户)实现IRepository(客户)的。新增    结束小组    公用Sub删除(BYVAL实体客户)实现IRepository(客户)的.Delete    结束小组    公共职能GetByID(BYVAL ID作为整数)作为客户,实现IRepository(顾客).GetByID
        返回新客户提供{.ID = ID,.FirstName =山姆,.LastName =斯特里亚诺}
    结束功能
末级公共类客户
    公共属性ID作为整数
    公共属性名字作为字符串
    公共属性名字作为字符串
末级


解决方案

我用得到的服务类实例化的通用库(使用依赖注入与Ninject)。

服务类实质上执行两个功能:


  1. 它提供了所有控制器将消耗的方法。


  2. 它有一个叫做物业视图模型,这基本上是意见需要到MyViewModel类映射数据。


控制器消费服务类。有了这个模式,你的控制器是这样的:

 命名空间ES.eLearningFE.Areas.Courses.Controllers
{
    公共部分类CourseController:控制器
    {
        ICourseDisplayService服务;
        公共CourseController(ICourseDisplayService服务)
        {
            this.service =服务;
        }        公共虚拟的ActionResult显示(INT CourseId,诠释StepOrder,串PupilName,串TutorName)
        {
            service.CourseId = CourseId;
            service.StepOrder = StepOrder;
            service.PupilName = PupilName;
            service.TutorName = TutorName;
            如果(Request.IsAjaxRequest())
            {
                返回PartialView(service.ViewModel);
            }
            其他
            {
                返回查看(service.ViewModel);
            }
        }    }
}

视图模型类只能容纳显示数据,并没有方法(除了奇非常简单的方法从另一个属性是检索数据,例如一个List<>对象)。

作品真的很好。服务类的一个示例:

 命名空间ES.eLearning.Domain.Services.Courses
{
    公共类SqlCourseDisplayService:ICourseDisplayService
    {
        DataContext的分贝;        公共SqlCourseDisplayService(DbDataContextFactory contextFactory)
        {
            DB = contextFactory.Make();
            CoursesRepository =新SqlRepository<课程和GT;(DB);
            StepsRepository =新SqlRepository< CourseStep>(DB);
            StepLinksRepository =新SqlRepository< StepLink>(DB);
            UserCoursesRepository =新SqlRepository< UserCourse>(DB);
            CourseTutorsRepository =新SqlRepository< CourseTutor>(DB);
            UsersRepository =新SqlRepository<使用者>(DB);
        }
        #区域ICourseDisplayService成员        公共ViewModels.CourseDisplayVM视图模型
        {
            得到
            {
                返回新ViewModels.CourseDisplayVM
                {
                    CourseId = this.CourseId,
                    课程名= this.Course.Name,
                    步骤= this.Steps,
                    ActiveStepIndex = this.ActiveStepIndex,
                    CurrentStepIndex = this.CurrentStepIndex,
                    多空=新UserDto {用户ID = this.PupilId,用户名= this.PupilName},
                    导师= this.GetTutors(this.CourseId)
                    导师= tutorName == NULL?空:新UserDto {用户名= this.TutorName,用户Id = this.TutorId}
                };
            }
        }        #区域实体        INT courseId;
        公众诠释CourseId
        {
            得到
            {
                如果(courseId == 0)抛出新ApplicationException的(无效的课程ID!);
                返回courseId;
            }
            组
            {
                如果(价值== 0)抛出新ApplicationException的(无效的课程ID!);
                尝试
                {
                    当然=(从C在CoursesRepository.Query那里c.CourseId ==价值选择C)。首先();
                    步骤= Course.CourseSteps.ToList();
                    courseId =价值;
                }
                抓{抛出新ApplicationException的(没有课程找到课程编号:+值);}
            }
        }        公共Data.Course课程{搞定;私人集; }        公众诠释StepOrder {搞定;组; }        公开名单< D​​ata.CourseStep>步骤{搞定;私人集; }        公众诠释ActiveStepIndex
        {
            得到
            {
                如果(PupilName == NULL)
                {
                    抛出新ApplicationException的(瞳没有设置!);
                }
                如果(CourseId == 0)
                {
                    抛出新ApplicationException的(课程未设定!);
                }
                尝试
                {
                    VAR X =(加州在那里UserCoursesRepository.Query(uc.IdCourse == CourseId)及及(uc.UserName == PupilName)选择UC)。首先();
                    返回x.ActiveStepIndex;
                }
                抓{抛出新ApplicationException的(无法得到有效步骤!); }
            }
        }        #endregion        #区域用户        串tutorName;
        公共字符串TutorName
        {
            得到
            {
                如果(tutorName == NULL)抛出新ApplicationException的(无效的调用来获取导师姓名[空导师姓名]!);
                返回tutorName;
            }
            组
            {
                tutorName =价值;
                TutorId =(GUID)Membership.GetUser(tutorName).ProviderUserKey;
            }
        }        公众的Guid TutorId {搞定;组; }        串pupilName;
        公共字符串PupilName
        {
            {返回pupilName; }
            组
            {
                pupilName =价值;
                PupilId =(GUID)Membership.GetUser(pupilName).ProviderUserKey;
            }
        }        公众的Guid PupilId {搞定;组; }        #endregion        #区域公用属性        公众诠释CurrentStepIndex {搞定;组; }
        公众诠释STEPCOUNT
        {
            得到
            {
                返回步骤== NULL? 0:Steps.Count();
            }
        }        #endregion        #地区的私营公用事业        私人列表< UserDto> GetTutors(INT CourseId)
        {
            在UsersRepository.Query返回(从CourseTutorsRepository.Query克拉走进你
                    在ct.TutorName等于u.UserName
                    其中(ct.CourseId == courseId)
                    选择新UserDto {用户名= ct.TutorName,用户Id = u.UserId})了ToList()。
        }        #endregion        #地区库        私人IRepository<课程和GT; CoursesRepository
        {
            得到;
            组;
        }        私人IRepository< CourseStep> StepsRepository
        {
            得到;
            组;
        }        私人IRepository< StepLink> StepLinksRepository
        {
            得到;
            组;
        }        私人IRepository< UserCourse> UserCoursesRepository
        {
            得到;
            组;
        }        私人IRepository< CourseTutor> CourseTutorsRepository
        {
            得到;
            组;
        }        私人IRepository<使用者> UsersRepository
        {
            得到;
            组;
        }        #endregion        #endregion
    }
}

也许不是每个人的选择,但嘿,这对我的作品... AND(更重要的),我的客户和他们的用户。

修改

的要求,在下面的评论,我使用Repository:

 命名空间ES.eLearning.Domain
{
    公共类SqlRepository< T> :IRepository< T>其中T:类
    {
        DataContext的分贝;
        公共SqlRepository(DataContext的DB)
        {
            this.db = DB;
        }        #地区IRepository< T>会员        公众的IQueryable< T>询问
        {
            {返回db.GetTable< T>(); }
        }        公开名单< T>使用fetchall()
        {
            返回Query.ToList();
        }        公共无效添加(T实体)
        {
            db.GetTable< T>()InsertOnSubmit(实体)。
        }        公共无效删除(T实体)
        {
            db.GetTable< T>()DeleteOnSubmit(实体)。
        }        公共无效连接(T实体)
        {
            db.GetTable< T>()连接(实体)。
        }        公共无效保存()
        {
            db.SubmitChanges();
        }        #endregion
    }
}

而IRepository接口:

 命名空间Wingspan.Web.Mvc
{
    公共接口IRepository< TEntity>其中,TEntity:类
    {
        清单< TEntity>使用fetchall();
        IQueryable的< TEntity>查询{搞定;}
        无效添加(TEntity实体);
        无效删除(TEntity实体);
        空连接(TEntity实体);
        无效保存();
    }
}

I am fairly new to MVC, but after playing with it (MVC 3/Razor), I am hooked.

I have a few questions:

1) What is the best, or most widely used pattern to develop MVC apps in? Repository, DDD, UOW?

2) I am using the Entity Framework 4, so could some please explain to me or point me to a good source that will explain the Repository Pattern w/EF4? Doesn't EF4 take place as the business layer and the data access layer? Does the Repository Pattern even provide a benefit?

3) Also, one last question, could someone explain the whole relationship between the Controller, the Model and the View? I get the basics, but maybe a little more in depth of the correct way to use it. View Models - Say I have a view that displays customer info, and one that edits it, should I have a view model and an edit model, or can the be passed around?

4) Examples??

Thanks for the help up front,
$("Sam")

** EDIT **

Am I on the right track here:

Public Class HomeController
    Inherits System.Web.Mvc.Controller

    Function Index(ByVal id As Integer) As ActionResult
        Return View(New HomeModel)
    End Function

    <HttpPost()> _
    Function Index(ByVal Model As HomeModel) As ActionResult
        Return View(Model)
    End Function

End Class

Public Class HomeModel
    Private _Repository As IRepository(Of Customer)

    Public Property Customer As Customer

    Public Sub New()

    End Sub

    Public Sub New(ByVal ID As Integer)
        _Repository = New CustomerRepository
        Customer = _Repository.GetByID(ID)
    End Sub

End Class

Public Interface IRepository(Of T)
    Function GetByID(ByVal ID As Integer) As T
    Sub Add(ByVal Entity As T)
    Sub Delete(ByVal Entity As T)

End Interface

Public Class CustomerRepository
    Implements IRepository(Of Customer)

    Public Sub Add(ByVal Entity As Customer) Implements IRepository(Of Customer).Add

    End Sub

    Public Sub Delete(ByVal Entity As Customer) Implements IRepository(Of Customer).Delete

    End Sub

    Public Function GetByID(ByVal ID As Integer) As Customer Implements IRepository(Of    Customer).GetByID
        Return New Customer With {.ID = ID, .FirstName = "Sam", .LastName = "Striano"}
    End Function
End Class

Public Class Customer
    Public Property ID As Integer
    Public Property FirstName As String
    Public Property LastName As String
End Class

解决方案

I use generic repositories that get instantiated in a service class (using Dependency Injection with Ninject).

The service class essentially performs two functions:

  1. It provides all the methods that the controller will consume.

  2. It has a property called ViewModel, that essentially maps the data that the views need into a MyViewModel class.

The Controller consumes the service class. With this "pattern", your controllers look like:

namespace ES.eLearningFE.Areas.Courses.Controllers
{
    public partial class CourseController : Controller
    {
        ICourseDisplayService service;
        public CourseController(ICourseDisplayService service)
        {
            this.service = service;
        }

        public virtual ActionResult Display(int CourseId, int StepOrder, string PupilName, string TutorName)
        {
            service.CourseId = CourseId;
            service.StepOrder = StepOrder;
            service.PupilName = PupilName;
            service.TutorName = TutorName;
            if (Request.IsAjaxRequest())
            {
                return PartialView(service.ViewModel);
            }
            else
            {
                return View(service.ViewModel);
            }
        }

    }
}

The ViewModel class only hold display data and no methods (except the odd really simple method to retrieve data from another property that is, for example a List<> object).

Works really well. An example of a service class:

namespace ES.eLearning.Domain.Services.Courses
{
    public class SqlCourseDisplayService : ICourseDisplayService
    {
        DataContext db;

        public SqlCourseDisplayService(DbDataContextFactory contextFactory)
        {
            db = contextFactory.Make();
            CoursesRepository      = new SqlRepository<Course>(db);
            StepsRepository        = new SqlRepository<CourseStep>(db);
            StepLinksRepository    = new SqlRepository<StepLink>(db);
            UserCoursesRepository  = new SqlRepository<UserCourse>(db);
            CourseTutorsRepository = new SqlRepository<CourseTutor>(db);
            UsersRepository        = new SqlRepository<User>(db);
        }
        #region ICourseDisplayService Members

        public ViewModels.CourseDisplayVM ViewModel
        {
            get
            {
                return new ViewModels.CourseDisplayVM
                {
                    CourseId = this.CourseId,
                    CourseName = this.Course.Name,
                    Steps = this.Steps,
                    ActiveStepIndex = this.ActiveStepIndex,
                    CurrentStepIndex = this.CurrentStepIndex,
                    Pupil = new UserDto { UserId = this.PupilId, UserName = this.PupilName },
                    Tutors = this.GetTutors(this.CourseId),
                    Tutor = tutorName == null ? null : new UserDto { UserName = this.TutorName, UserId = this.TutorId}
                };
            }
        }

        #region Entities

        int courseId;
        public int CourseId
        {
            get
            {
                if (courseId == 0) throw new ApplicationException("Invalid Course Id!");
                return courseId;
            }
            set
            {
                if (value == 0) throw new ApplicationException("Invalid Course Id!");
                try
                {
                    Course   = (from c in CoursesRepository.Query where c.CourseId == value select c).First();
                    Steps    = Course.CourseSteps.ToList();
                    courseId = value;
                }
                catch {throw new ApplicationException("No Course found for Course Id: " + value);}
            }
        }

        public Data.Course Course { get; private set; }

        public int StepOrder { get; set; }

        public List<Data.CourseStep> Steps { get; private set; }

        public int ActiveStepIndex
        {
            get
            {
                if (PupilName == null)
                {
                    throw new ApplicationException("Pupil not set!");
                }
                if (CourseId == 0)
                {
                    throw new ApplicationException("Course not set!");
                }
                try
                {
                    var x = (from uc in UserCoursesRepository.Query where (uc.IdCourse == CourseId) && (uc.UserName == PupilName) select uc).First();
                    return x.ActiveStepIndex;
                }
                catch { throw new ApplicationException("Could not get Active Step!"); }
            }
        }

        #endregion

        #region Users

        string tutorName;
        public string TutorName
        {
            get 
            {
                if (tutorName == null) throw new ApplicationException("Invalid call to get Tutor Name [Null Tutor Name]!");
                return tutorName; 
            }
            set
            {
                tutorName = value;
                TutorId = (Guid)Membership.GetUser(tutorName).ProviderUserKey;
            }
        }

        public Guid TutorId { get; set; }

        string pupilName;
        public string PupilName
        {
            get { return pupilName; }
            set
            {
                pupilName = value;
                PupilId = (Guid)Membership.GetUser(pupilName).ProviderUserKey;
            }
        }

        public Guid PupilId { get; set; }

        #endregion

        #region Utility Properties

        public int CurrentStepIndex { get; set; }
        public int StepCount
        {
            get
            {
                return Steps == null ? 0 : Steps.Count();
            }
        }

        #endregion

        #region Private Utilities

        private List<UserDto> GetTutors(int CourseId)
        {
            return (from ct in CourseTutorsRepository.Query join u in UsersRepository.Query
                    on ct.TutorName equals u.UserName
                    where (ct.CourseId == courseId) 
                    select new UserDto { UserName = ct.TutorName, UserId = u.UserId }).ToList();
        }

        #endregion

        #region Repositories

        private IRepository<Course> CoursesRepository
        {
            get;
            set;
        }

        private IRepository<CourseStep> StepsRepository
        {
            get;
            set;
        }

        private IRepository<StepLink> StepLinksRepository
        {
            get;
            set;
        }

        private IRepository<UserCourse> UserCoursesRepository
        {
            get;
            set;
        }

        private IRepository<CourseTutor> CourseTutorsRepository
        {
            get;
            set;
        }

        private IRepository<User> UsersRepository
        {
            get;
            set;
        }

        #endregion

        #endregion
    }
}

May not be everyone's choice, but hey, it works for me... AND (more importantly) my clients and their users.

Edit

As requested in the comment below, the Repository that I use:

namespace ES.eLearning.Domain
{
    public class SqlRepository<T> : IRepository<T> where T : class
    {
        DataContext db;
        public SqlRepository(DataContext db)
        {
            this.db = db;
        }

        #region IRepository<T> Members

        public IQueryable<T> Query
        {
            get { return db.GetTable<T>(); }
        }

        public List<T> FetchAll()
        {
            return Query.ToList();
        }

        public void Add(T entity)
        {
            db.GetTable<T>().InsertOnSubmit(entity);
        }

        public void Delete(T entity)
        {
            db.GetTable<T>().DeleteOnSubmit(entity);
        }

        public void Attach(T entity)
        {
            db.GetTable<T>().Attach(entity);
        }

        public void Save()
        {
            db.SubmitChanges();
        }

        #endregion
    }
}

And the IRepository Interface:

namespace Wingspan.Web.Mvc
{
    public interface IRepository<TEntity> where TEntity : class
    {
        List<TEntity> FetchAll();
        IQueryable<TEntity> Query {get;}
        void Add(TEntity entity);
        void Delete(TEntity entity);
        void Attach(TEntity entity);
        void Save();
    }
}

这篇关于ASP.NET MVC模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆