ASP.NET MVC Patterns

后端 未结 4 1161
一向
一向 2021-01-15 09:07

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 dev

4条回答
  •  栀梦
    栀梦 (楼主)
    2021-01-15 09:32

    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(db);
                StepsRepository        = new SqlRepository(db);
                StepLinksRepository    = new SqlRepository(db);
                UserCoursesRepository  = new SqlRepository(db);
                CourseTutorsRepository = new SqlRepository(db);
                UsersRepository        = new SqlRepository(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 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 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 CoursesRepository
            {
                get;
                set;
            }
    
            private IRepository StepsRepository
            {
                get;
                set;
            }
    
            private IRepository StepLinksRepository
            {
                get;
                set;
            }
    
            private IRepository UserCoursesRepository
            {
                get;
                set;
            }
    
            private IRepository CourseTutorsRepository
            {
                get;
                set;
            }
    
            private IRepository 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 : IRepository where T : class
        {
            DataContext db;
            public SqlRepository(DataContext db)
            {
                this.db = db;
            }
    
            #region IRepository Members
    
            public IQueryable Query
            {
                get { return db.GetTable(); }
            }
    
            public List FetchAll()
            {
                return Query.ToList();
            }
    
            public void Add(T entity)
            {
                db.GetTable().InsertOnSubmit(entity);
            }
    
            public void Delete(T entity)
            {
                db.GetTable().DeleteOnSubmit(entity);
            }
    
            public void Attach(T entity)
            {
                db.GetTable().Attach(entity);
            }
    
            public void Save()
            {
                db.SubmitChanges();
            }
    
            #endregion
        }
    }
    

    And the IRepository Interface:

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

提交回复
热议问题