热门标签 | 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后台权限管理系统(附源码下载)

 




推荐阅读
  • 调料|信息源_MVI到底是不是凑数的?通过案例与MVVM进行比较
    调料|信息源_MVI到底是不是凑数的?通过案例与MVVM进行比较 ... [详细]
  • EasyMock实战指南
    本文介绍了如何使用EasyMock进行单元测试,特别是当测试对象的合作者依赖于外部资源或尚未实现时。通过具体的示例,展示了EasyMock在模拟对象行为方面的强大功能。 ... [详细]
  • 本文探讨了如何在Classic ASP中实现与PHP的hash_hmac('SHA256', $message, pack('H*', $secret))函数等效的哈希生成方法。通过分析不同实现方式及其产生的差异,提供了一种使用Microsoft .NET Framework的解决方案。 ... [详细]
  • 优化SQL Server批量数据插入存储过程的实现
    本文介绍了一种改进的SQL Server存储过程,用于生成批量插入语句。该方法不仅提高了性能,还支持单行和多行模式,适用于SQL Server 2005及以上版本。 ... [详细]
  • SpringMVC RestTemplate的几种请求调用(转)
    SpringMVCRestTemplate的几种请求调用(转),Go语言社区,Golang程序员人脉社 ... [详细]
  • Java EE CDI:解决依赖关系冲突的实例
    在本教程中,我们将探讨如何在Java EE的CDI(上下文和依赖注入)框架中有效解决依赖关系的冲突问题。通过学习如何使用限定符,您将能够为应用程序的不同客户端提供多种接口实现,并确保每个客户端都能正确调用其所需的实现。 ... [详细]
  • 在 Android 开发中,通过 Intent 启动 Activity 或 Service 时,可以使用 putExtra 方法传递数据。接收方可以通过 getIntent().getExtras() 获取这些数据。本文将介绍如何使用 RoboGuice 框架简化这一过程,特别是 @InjectExtra 注解的使用。 ... [详细]
  • 云函数与数据库API实现增删查改的对比
    本文将深入探讨使用云函数和数据库API实现数据操作(增删查改)的不同方法,通过详细的代码示例帮助读者更好地理解和掌握这些技术。文章不仅提供代码实现,还解释了每种方法的特点和适用场景。 ... [详细]
  • 深入解析Spring启动过程
    本文详细介绍了Spring框架的启动流程,帮助开发者理解其内部机制。通过具体示例和代码片段,解释了Bean定义、工厂类、读取器以及条件评估等关键概念,使读者能够更全面地掌握Spring的初始化过程。 ... [详细]
  • 配置PHPStudy环境并使用DVWA进行Web安全测试
    本文详细介绍了如何在PHPStudy环境下配置DVWA( Damn Vulnerable Web Application ),并利用该平台进行SQL注入和XSS攻击的练习。通过此过程,读者可以熟悉常见的Web漏洞及其利用方法。 ... [详细]
  • 本文详细介绍了get和set方法的作用及其在编程中的实现方式,同时探讨了点语法的使用场景。通过具体示例,解释了属性声明与合成存取方法的概念,并补充了相关操作的最佳实践。 ... [详细]
  • 烤鸭|本文_Spring之Bean的生命周期详解
    烤鸭|本文_Spring之Bean的生命周期详解 ... [详细]
  • 尽管PHP是一种强大且灵活的Web开发语言,但开发者在使用过程中常会陷入一些典型的陷阱。本文旨在列出PHP开发中最为常见的10种错误,并提供相应的预防建议。 ... [详细]
  • 在CentOS 7上轻松安装Elasticsearch的JDBC插件
    本文介绍如何在CentOS 7操作系统中安装Elasticsearch (简称ES) 的JDBC插件,以实现与MySQL数据库的有效连接,特别强调了该方法对于增量数据同步的支持。 ... [详细]
  • 近期,公司在构建新的交易系统时遇到了一个常见的问题——金额存储。由于涉及资金的操作需要高度的准确性,使用float类型进行金额计算可能会导致不可预见的误差。本文将深入探讨这一问题,并提供解决方案。 ... [详细]
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社区 版权所有