ASP.NET MVC模式 [英] ASP.NET MVC Patterns
问题描述
我是相当新的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)。
服务类实质上执行两个功能:
-
它提供了所有控制器将消耗的方法。
-
它有一个叫做物业视图模型,这基本上是意见需要到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 {搞定;组; } 公开名单< Data.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:
It provides all the methods that the controller will consume.
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屋!