Project Silk – Mileage Stats 项目架构初步分析(ASP.NET MVC 3)

简介:

如果你正在学习ASP.NET MVC 3HTML5jQuery和浏览器客户端交互技术,推荐你下载Mileage Stats 范例程序,可更好理解如何使用当前技术创建当前的web应用程序,尤其关注如何架构一个企业级的应用程序。关于Mileage Stats项目的初步介绍,请参考《Project Silk  基于ASP.NET MVC 3 的示例应用程序Mileage Stats》。

 

EntLib.com Team 尝试从架构的角度对MileageStats项目进行分析和解读,并计划运用到实际的电子商务系统中,欢迎大家参与交流和分享。

 

MileageStats RI 运行的主要界面:

 


 

 

MileageStats RI 项目的当前架构图,主要有Web 表示层、业务逻辑层和数据访问层,如下图所示。

 

 


 

 

简要看看MileageStats 包含的一些主要项目:

 


 

 

 

创建数据模型(Data Model

MileageStats.Model 项目包含数据模型(Data Model)。结构化和强类型的类描述了业务数据的数据类型、关系和约束。

 

实现Repository Pattern

Repository模式中,Repository是一组接口,实现了数据访问相关的方法。接口没有暴露任何特定数据存储相关的类型。

MileageStats.Data 项目包含了Repository接口,MileageStats.Data.SqlCe 项目包含了接口的实现。如下是IReminderRepository 接口的示例代码:

// contained in IReminderRepository.cs

public interface IReminderRepository

{

void Create(int vehicleId, Reminder reminder);

Reminder GetReminder(int reminderId);

void Update(Reminder reminder);

void Delete(int reminderId);

 

IEnumerable<Reminder> GetRemindersForVehicle(int vehicleId);

IEnumerable<Reminder> GetOverdueReminders(int vehicleId,

DateTime forDate, int forOdometer);

 

IEnumerable<Reminder> GetUpcomingReminders(int vehicleId,

DateTime forStartDate, DateTime forEndDate,

int odometer, int warningOdometer);

 

IEnumerable<Reminder> GetFulfilledRemindersForVehicle(int vehicleId);

}

 

分解应用程序代码到ASP.NET MVC模式

设计良好的MVC应用程序保持ControllerAction方法比较小,View比较简单。大部分的核心应用程序逻辑存放在Model中。在MVC应用程序创建时,保持DRYDon’t Repeat Yourself)原则比后期试图清理代码更容易。

 

因为大部分应用程序逻辑在Model层中,因此很多MVC 应用程序包含不同类型的Model

View models(视图模型) - 仅用于视图的数据绑定,这些Models包含于MVC 应用程序中,一般与ViewsPartial Views保持相同的构成结构。

Application, domain, or service models(业务模型) - 基于实际业务需要建立的数据模型,可添加属性标注,或扩展支持应用功能,如数据验证、身份验证。因为这些Models易于往返于客户端浏览器,因此它们经常包含于View Models,并直接在HTML 表单进行数据绑定。

Data models(数据模型) - 用于数据服务和存储,不会暴露在应用程序之外,经常封装在服务层。

 

如下是MileageStats RI Solution中包含的3Model项目 – 下图中选中的项目,分别在Web层、业务逻辑层和数据层:

 


 

 

对于比较复杂或长期维护的应用程序,应该分离业务模型和数据模型。如果业务模型和数据模型的层级和接口差异很大,则创建完全分离的类。如业务模型和数据模型有匹配的层级和兼容的接口,则建议业务模型类继承数据模型类。如业务模型和数据模型有匹配的层级,但接口不兼容(如数据模型类接口不适合于业务模型类),则在业务模型类中通过聚集关系,包含数据模型类实例。

 


 

在编写Controller Action方法时,应将一些复杂的方法包装为modelservice层的辅助方法或类中。优先采用action过滤器属性,如HttpPostAttribute,避免在每一个action方法中检测HttpContext,编写逻辑判断。此外,使用action过滤器进行横切关切点(Cross-cutting concern),如认证(AuthorizeAttribute)、错误处理(HandleErrorAttribute)等等。处理GET请求的方法应仅包含一些方法调用,而不必包含太多业务判断逻辑;处理POST 请求的方法应验证传入的数据,在数据合法的情况下,执行更新操作,并根据更新结果,返回对应视图。MileageStats RI 应用程序的如下范例显示2个版本的Add方法(分别为GETPOST版本):

        // GET: /Fillups/Add/1

        public ActionResult Add(int vehicleId)

        {

            var vehicles = this.businessServices.GetVehicles(this.User.MileageStatsIdentity().UserId);

            Vehicle vehicle = vehicles.First(v => v.VehicleId == vehicleId);

 

            var newFillupEntry = new FillupEntry()

            {

                Odometer = vehicle.Odometer.HasValue ? vehicle.Odometer.Value : 0

            };

            var fillups = this.GetVehicleFillupsDescending(vehicleId);

 

            var model = new FillupViewModel()

            {

                VehicleList = new VehicleListViewModel(vehicles, vehicle) { IsCollapsed = true },

                Fillups = new SelectedItemList<FillupEntry>(fillups, newFillupEntry),

                FillupEntry = newFillupEntry

            };

 

            this.ViewBag.IsFirstFillup = (fillups.Count == 0);

 

            return this.View(model);

        }

 

        //

        // POST: /Fillups/Add/5

        [HttpPost]

        [ValidateInput(false)]

        [ValidateAntiForgeryToken]

        public ActionResult Add(int vehicleId, FillupEntry model)

        {

            if (this.ModelState.IsValid)

            {

                this.AddModelErrors(this.businessServices.CanAddFillup(this.CurrentUserId, vehicleId, model),

                                    "AddFillup");

 

                if (this.ModelState.IsValid)

                {

                    this.businessServices.AddFillupToVehicle(this.CurrentUserId, vehicleId, model);

                    this.TempData["LastActionMessage"] = Resources.VehicleController_AddFillupSuccessMessage;

                    return this.RedirectToAction("List""Fillup"new { vehicleId = vehicleId });

                }

            }

 

            var vehicles = this.businessServices.GetVehicles(this.CurrentUserId);

            Vehicle vehicle = vehicles.First(v => v.VehicleId == vehicleId);

            var fillups = this.GetVehicleFillupsDescending(vehicleId);

 

            var viewModel = new FillupViewModel()

            {

                VehicleList = new VehicleListViewModel(vehicles, vehicle) { IsCollapsed = true },

                Fillups = new SelectedItemList<FillupEntry>(fillups, model),

                FillupEntry = model

            };

 

            this.ViewBag.IsFirstFillup = (fillups.Count == 0);

 

            return this.View(viewModel);

        }

 

 

依赖注入 - Dependency Injection

解耦应用程序的组件(Decoupling the application components)。关于Unity 2.0 依赖注入容器在ASP.NET MVC 3 项目的具体使用细节,可参考文章 - ASP.NET MVC 项目使用Unity 2.0实现依赖注入

 

创建Business Service 

为了项目的可维护和支持不同类型的客户端,大型和复杂的应用程序经常需要额外的架构层 – Business Service Layer,将业务逻辑从数据访问层分离出来。

 

本文参考和编译了如下文章部分内容:

Project Silk 1.0 – Server-side Architecture

Project Silk - http://silk.codeplex.com/










本文转自 entlib.com 51CTO博客,原文链接:http://blog.51cto.com/entlib/569205,如需转载请自行联系原作者
目录
相关文章
|
26天前
|
人工智能 自然语言处理 数据可视化
两大 智能体框架 Dify vs Langchain 的全面分析,该怎么选?资深架构师 做一个彻底的解密
两大 智能体框架 Dify vs Langchain 的全面分析,该怎么选?资深架构师 做一个彻底的解密
两大 智能体框架 Dify vs Langchain 的全面分析,该怎么选?资深架构师 做一个彻底的解密
|
4月前
|
机器学习/深度学习 安全 算法
十大主流联邦学习框架:技术特性、架构分析与对比研究
联邦学习(FL)是保障数据隐私的分布式模型训练关键技术。业界开发了多种开源和商业框架,如TensorFlow Federated、PySyft、NVFlare、FATE、Flower等,支持模型训练、数据安全、通信协议等功能。这些框架在灵活性、易用性、安全性和扩展性方面各有特色,适用于不同应用场景。选择合适的框架需综合考虑开源与商业、数据分区支持、安全性、易用性和技术生态集成等因素。联邦学习已在医疗、金融等领域广泛应用,选择适配具体需求的框架对实现最优模型性能至关重要。
983 79
十大主流联邦学习框架:技术特性、架构分析与对比研究
|
2月前
|
存储 数据采集 机器学习/深度学习
新闻聚合项目:多源异构数据的采集与存储架构
本文探讨了新闻聚合项目中数据采集的技术挑战与解决方案,指出单纯依赖抓取技术存在局限性。通过代理IP、Cookie和User-Agent的精细设置,可有效提高采集策略;但多源异构数据的清洗与存储同样关键,需结合智能化算法处理语义差异。正反方围绕技术手段的有效性和局限性展开讨论,最终强调综合运用代理技术与智能数据处理的重要性。未来,随着机器学习和自然语言处理的发展,新闻聚合将实现更高效的热点捕捉与信息传播。附带的代码示例展示了如何从多个中文新闻网站抓取数据并统计热点关键词。
115 2
新闻聚合项目:多源异构数据的采集与存储架构
|
2月前
|
人工智能 前端开发 Java
DDD四层架构和MVC三层架构的个人理解和学习笔记
领域驱动设计(DDD)是一种以业务为核心的设计方法,与传统MVC架构不同,DDD将业务逻辑拆分为应用层和领域层,更关注业务领域而非数据库设计。其四层架构包括:Interface(接口层)、Application(应用层)、Domain(领域层)和Infrastructure(基础层)。各层职责分明,避免跨层调用,确保业务逻辑清晰。代码实现中,通过DTO、Entity、DO等对象的转换,结合ProtoBuf协议,完成请求与响应的处理流程。为提高复用性,实际项目中可增加Common层存放公共依赖。DDD强调从业务出发设计软件,适应复杂业务场景,是微服务架构的重要设计思想。
|
3月前
|
人工智能 JavaScript 安全
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
159 13
【01】Java+若依+vue.js技术栈实现钱包积分管理系统项目-商业级电玩城积分系统商业项目实战-需求改为思维导图-设计数据库-确定基础架构和设计-优雅草卓伊凡商业项目实战
|
3月前
|
SQL 运维 BI
湖仓分析|浙江霖梓基于 Doris + Paimon 打造实时/离线一体化湖仓架构
浙江霖梓早期基于 Apache Doris 进行整体架构与表结构的重构,并基于湖仓一体和查询加速展开深度探索与实践,打造了 Doris + Paimon 的实时/离线一体化湖仓架构,实现查询提速 30 倍、资源成本节省 67% 等显著成效。
湖仓分析|浙江霖梓基于 Doris + Paimon 打造实时/离线一体化湖仓架构
|
2月前
|
前端开发 JavaScript API
体育赛事即时比分 分析页面的开发技术架构与实现细节
本文基于“体育即时比分系统”开发经验总结,分享技术实现细节。系统通过后端(ThinkPHP)、前端(Vue.js)、移动端(Android/iOS)协同工作,解决实时比分更新、赔率同步及赛事分析展示等问题。前端采用 Vue.js 结合 WebSocket 实现数据推送,提升用户体验;后端提供 API 支持比赛数据调用;移动端分别使用 Java 和 Objective-C 实现跨平台功能。代码示例涵盖比赛分析页面、API 接口及移动端数据加载逻辑,为同类项目开发提供参考。
|
4月前
|
开发框架 前端开发 .NET
一个适用于 .NET 的开源整洁架构项目模板
一个适用于 .NET 的开源整洁架构项目模板
95 26
|
3月前
|
传感器 人工智能 机器人
D1net阅闻|OpenAI机器人项目招新 或自研传感器
D1net阅闻|OpenAI机器人项目招新 或自研传感器
|
4月前
|
开发框架 安全 .NET
【Azure Developer】.NET Aspire 项目本地调试遇 Grpc.Core.RpcException 异常( Error starting gRPC call ... )
Error starting gRPC call. HttpRequestException: The SSL connection could not be established, see inner exception. AuthenticationException: The remote certificate is invalid because of errors in the certificate chain: UntrustedRoot
106 12