热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

利用StructureMap在ASP.NETMVC三层架构中实现依赖注入的扩展方法与实践

本文将介绍一种扩展的ASP.NETMVC三层架构框架,并通过使用StructureMap实现依赖注入,以降低代码间的耦合度。该方法不仅能够提高代码的可维护性和可测试性,还能增强系统的灵活性和扩展性。通过具体实践案例,详细阐述了如何在实际开发中有效应用这一技术。

今天开始天屹将给大家分享一个扩展的ASP.NET MVC三层框架,并使用StructureMap实现依赖注入,充分的使代码之间的耦合度降到最低。由于时间精力有限天屹无法在一篇文章中全部介绍完,将把文章写成一个系列文章。系统将使用最新的MVC4和EntityFramework5.0。众所周知MVC4新建的默认工程很简单,而且Model层是和Views,Controller在一个Project里面的,这样的结构很不美观也很不利于维护,最重要的一点没有Service层和Repository层。

本篇文章将向大家介绍如何添加Service和Repository层并且使用StructureMap把Service层注入到Controller,把Repository注入到Service层。Service层主要是我们的业务逻辑层,这一层不和底层的Database打交道,和Database打交道的是Repository数据持久层。本篇文章通过使用StructureMap依赖注入使Controller,Service,Repository三层的耦合度降到最低。

本系统使用NorthWind开源数据,并且使用EntityFramework5.0实现对数据库的Object映射。

开始正题之前先来看一下成型的框架结构,我们将围绕这个截图进行展开。

mvc-customized-framework

 

 

 

 

 

首先我们看TYStudioDemo.Models这个Project里面的内容

mvc-customized-framework

这里面有我们的EntityFramwork的edmx文件,Northwind的数据库表映射的对象集合。这里建立ADO.Net Entity Data Model的时候没有使用默认生成一堆.tt文件的方式,而是使用了老的形式。实现方法是首先按默认程序建立起data model,建立好data model之后删除.tt文件。然后打开.edmx文件,右键单击空白处选择Properties(属性),会出现下面的截图,这时候只需要修改一下Code Generation Strategy(中文翻译不知道是什么,第一个就对了)的值,默认是None,我们修改为Default,然后保存.edmx,ok,万事大吉。

edmx-propertoties

你应该已经注意到了,项目里多了一个TYEntities.cs文件,这个我们是我们这个系统中实现Transaction(事务处理)的关键。
我们使用static和[ThreadStatic]属性来保证一个线程拿到的TYEntities(ObjectContext)总是同一个,这就解决了Transaction事务的问题。没有解释到的请详细阅读下面代码里面的注释。  

1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Threading.Tasks;
6 using System.Web;
7
8 namespace TYStudioDemo.Models
9 {
10 public partial class TYEntities
11 {
12 #region Fields
13
14 //定义索引名称
15 const string ContextKey = "TYEntities";
16
17 //标记为ThreadStaticAttribute的静态字段不在线程之间共享。
18 //每个执行线程都有单独的字段实例,并且独立地设置及获取该字段的值。如果在不同的线程中访问该字段,则该字段将包含不同的值。
19 [ThreadStatic]
20 private static TYEntities _current;
21
22 #endregion
23
24 #region Properties
25
26 public bool Disposed { get; set; }
27
28 ///


29 /// 当系统工作在HttpContext下,将使用延迟家在技术返回一个TYEntities(ObjectContext),如果没有HttpContext将返回null
30 ///
31 /// 不论在哪里使用TYEntities,在请求结束后都需要调用TYEntities.Cleanup()方法
32 /// 最佳的方式是TYEntities.Cleanup()放到Global.asax.cs文件里面。
33 /// void Application_EndRequest(object sender, EventArgs e)
34 /// {
35 /// TYStudioDemo.Models.TYEntities.Cleanup();
36 /// }
37 ///

38 private static TYEntities ForWebRequest
39 {
40 get
41 {
42 var context = HttpContext.Current;
43
44 //检查HttpContext是否存在
45 if (context != null)
46 {
47 //试着从context中得到TYEntities
48 var result = context.Items[ContextKey] as TYEntities;
49
50 if (result == null)
51 {
52 //创建新的datacontext,并且保存到context里面
53 result = new TYEntities();
54 context.Items[ContextKey] = result;
55 }
56
57 return result;
58 }
59
60 return null;
61 }
62 }
63
64 ///
65 /// 这是一个用来获取TYEntities(ObjectContext)的公共属性
66 ///
67 /// 如果你通过HttpContext获取TYEntities,同样不论在哪里使用TYEntities,在请求结束后都需要调用TYEntities.Cleanup()方法
68 ///
69 /// 如果没有通过HttpContext获取TYEntities,你必须在使用结束之后调用TYEntities.Cleanup()方法,来清理ObjectContext。
70 ///
71 /// 需要注意的一点是,无论使用哪种方式获取TYEntities,我们都必须手动的清理和Dispose TYEntities(ObjectContext)。
72 /// 所以一定不要在using块中使用TYEntities(ObjectContext)。
73 ///

74 public static TYEntities Current
75 {
76 get
77 {
78 //从HttpContext中获取datacontext
79 var result = TYEntities.ForWebRequest;
80
81 if (result != null)
82 return result;
83
84 //试着获取当前活动的TYEntities
85 if (_current == null)
86 _current = new TYEntities();
87
88 return _current;
89 }
90 }
91
92 ///
93 /// 清理结束TYEntities(ObjectContext)
94 ///

95 public static void Cleanup()
96 {
97 if (HttpContext.Current != null)
98 {
99 var result = HttpContext.Current.Items[ContextKey] as TYEntities;
100
101 if (result != null)
102 result.Dispose();
103
104 HttpContext.Current.Items[ContextKey] = null;
105 }
106 else if (_current != null)
107 {
108 _current.Dispose();
109 _current = null;
110 }
111 }
112
113
114 protected override void Dispose(bool disposing)
115 {
116 bool disposed = Disposed;
117 Disposed = true;
118
119 if (!disposed)
120 Cleanup();
121
122 base.Dispose(disposing);
123 }
124
125 #endregion
126 }
127 }

由于时间问题,今天就先介绍TYStudio.Models的实现。在以后的文章中会陆续介绍各个Project的内容,所有Project介绍完之后,会在工程中加入日志和异常的处理,我们使用EnterPrise Library来实现他们。同时也会把天屹前段时间写的MVC4 Simplemembership权限管理的系统集成进来。

天屹一定抽出时间会尽快更新完成这一系列的文章,全部文章结束之后天屹会公开分享系统的代码供大家下载。

如果觉得文章内容还行,请点一下推荐,让更多的人看见,天屹会有更多的动力写下去,并且完善系统。原创文章转载请注明出处,谢谢。

相关文章

  • Simplemembership实现用户权限管理-扩展数据库
  • MVC4 Simplemembership实现用户权限管理-权限控制
  • Simplemembership实现用户权限管理-初步认识
  • MVC4 Simplemembership后台权限管理系统(附源码下载)

 




推荐阅读
  • 本文探讨了在使用JavaMail发送电子邮件时,抄送功能未能正常工作的问题,并提供了详细的代码示例和解决方法。 ... [详细]
  • 本文探讨了如何通过Service Locator模式来简化和优化在B/S架构中的服务命名访问,特别是对于需要频繁访问的服务,如JNDI和XMLNS。该模式通过缓存机制减少了重复查找的成本,并提供了对多种服务的统一访问接口。 ... [详细]
  • Beetl是一款先进的Java模板引擎,以其丰富的功能、直观的语法、卓越的性能和易于维护的特点著称。它不仅适用于高响应需求的大型网站,也适合功能复杂的CMS管理系统,提供了一种全新的模板开发体验。 ... [详细]
  • H5技术实现经典游戏《贪吃蛇》
    本文将分享一个使用HTML5技术实现的经典小游戏——《贪吃蛇》。通过H5技术,我们将探讨如何构建这款游戏的两种主要玩法:积分闯关和无尽模式。 ... [详细]
  • Docker安全策略与管理
    本文探讨了Docker的安全挑战、核心安全特性及其管理策略,旨在帮助读者深入理解Docker安全机制,并提供实用的安全管理建议。 ... [详细]
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • 本文详细介绍了 `org.apache.tinkerpop.gremlin.structure.VertexProperty` 类中的 `key()` 方法,并提供了多个实际应用的代码示例。通过这些示例,读者可以更好地理解该方法在图数据库操作中的具体用途。 ... [详细]
  • 本文详细介绍了在Linux操作系统上安装和部署MySQL数据库的过程,包括必要的环境准备、安装步骤、配置优化及安全设置等内容。 ... [详细]
  • 本文详细介绍了 Java 中 org.w3c.dom.Node 类的 isEqualNode() 方法的功能、参数及返回值,并通过多个实际代码示例来展示其具体应用。此方法用于检测两个节点是否相等,而不仅仅是判断它们是否为同一个对象。 ... [详细]
  • 在尝试启动Java应用服务器Tomcat时,遇到了org.apache.catalina.LifecycleException异常。本文详细记录了异常的具体表现形式,并提供了有效的解决方案。 ... [详细]
  • 在尝试加载支持推送通知的iOS应用程序的Ad Hoc构建时,遇到了‘no valid aps-environment entitlement found for application’的错误提示。本文将探讨此错误的原因及多种可能的解决方案。 ... [详细]
  • 本文介绍了如何在两个Oracle数据库(假设为数据库A和数据库B)之间设置DBLink,以便能够从数据库A中直接访问和操作数据库B中的数据。文章详细描述了创建DBLink前的必要准备步骤以及具体的创建方法。 ... [详细]
  • 如何高效解决Android应用ANR问题?
    本文介绍了ANR(应用程序无响应)的基本概念、常见原因及其解决方案,并提供了实用的工具和技巧帮助开发者快速定位和解决ANR问题,提高应用的用户体验。 ... [详细]
  • 本文介绍了一个使用Spring框架和Quartz调度器实现每周定时调用Web服务获取数据的小项目。通过详细配置Spring XML文件,展示了如何设置定时任务以及解决可能遇到的自动注入问题。 ... [详细]
  • JavaScript 实现图片文件转Base64编码的方法
    本文详细介绍了如何使用JavaScript将用户通过文件输入控件选择的图片文件转换为Base64编码字符串,适用于Web前端开发中图片上传前的预处理。 ... [详细]
author-avatar
捕风的水中龙_106
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有