一起谈.NET技术,Visual Studio 2010层架构验证的实现

简介:   当设计一个应用程序时,基本的要求是所有的通信信息交互都要通过定义的接口进行,不能让应用程序直接调用该接口的类别或方法。所以,可以通过Layer Diagram来展示这个架构上的想法。  我们将使用一段非常简单的代码,主要强调的是代码所代表的概念,而不是代码的细节。

  当设计一个应用程序时,基本的要求是所有的通信信息交互都要通过定义的接口进行,不能让应用程序直接调用该接口的类别或方法。所以,可以通过Layer Diagram来展示这个架构上的想法。

  我们将使用一段非常简单的代码,主要强调的是代码所代表的概念,而不是代码的细节。并将在现有代码层关系架构逻辑设计分析的基础上进行层验证(Layer Validation)功能:

  ①打开Visual Studio 2010,通过Modeling Projects模板指定解决方案(Solution)的名称为LayerValidation(File|New|Project命令,选择ModelingProject,命名为LayerValidation),并提供创建一个名为“Client”的C#控制台程序,单击“OK”按钮。

  ②在解决方案浏览器中,使用鼠标右键单击Solution节点,选择“New Project…”命令,在弹出的对话框中选择“Class Library”并将工程命名为“Implementation”。

  ③重复以上几步,创建名为“Interfaces”和“Creators”的Class Library工程。展开Interfaces工程节点,用鼠标右键单击Class1.cs,选择“Rename”命令,将该文件重命名为“IDataRetriever.cs”,并在弹出的对话框中选择“Yes”。文档编辑窗口和Solution Explorer如图5所示。

图5  文档编辑窗口和Solution Explorer

  ④把class的关键字改为interface,将IDataRetriever变成一个接口。为IDataRetriever添加一个get属性,该属性返回一个IData类型的对象。在IData下面有红色波浪线,表示IData不存在。Visual Studio 2010的新功能可以自动解决这个问题:用鼠标右键单击出错的IData,选择“Generate”命令,然后选择“Other…”命令,将看到一个“New Type”对话框。将其中的“Access:”修改为“public”,将“Kind:”修改为“interface”,其他的保留默认设置,单击“OK”按钮。VS会自动向Interfaces工程添加一个IData.cs文件,并在文件中创建一个名为IData的接口。

  ⑤展开Implementation工程节点,用鼠标右键单击References节点,选择“Add Reference…”命令,在弹出的对话框中选择Projects页,然后选择Interfaces工程,单击“OK”按钮。

  ⑥将Class1.cs重命名为DataRetriever.cs。打开DataRetriever.cs文件,修改DataRetriever类使其实现IDataRetriever接口。当输入IDataRetriever的时候没有出现智能输入支持,可以手动输入IDataRetriever,然后会发现IDataRetriever下面又出现了红色波浪线。将鼠标移动到IDataRetriever上,会注意到在这个单词开始的位置下方有一个方形的小图标。单击它并选择“using Interfaces;”命令,它会自动为你添加所需的using语句,如图6所示。 

图6  自动化提示添加代码语句(名字空间)

  现在“using Interfaces”已经自动添加好了。再次选中这个图标,不过这次选择“Implement interface ‘IDataRetriever’”命令,可自动生成“DataRetriever”代码文件。如上所示,创建了一个对象,调用了对象的一个属性,然后抛出一个“NotImplementedException”异常,程序描述了一个实际系统中经常遇到的问题。

  ⑧接下来向Client工程中添加到Implementation和Interfaces工程的引用。打开Client工程中的Program.cs文件,参考代码如下:

 
 
using System;
using System.Collections.Generic;
.
using System.Linq;
using System.Text;
using Implementation;
using Interfaces;

namespace Client
{
class Program
{
static void Main( string [] args)
{
DataRetriever dr
= new DataRetriever();
IData data
= dr.Data;
}
}
}

  在这段代码中,Client工程直接访问了一个接口(IDataRetriever)的实例(DataRetriever)。在没有需求功能扩展前没有太大问题,因为所有的数据是从DataRetriever中获取(可以想象DataRetriever是从SQL数据库中获取的数据)。如果将来需要从另一种数据源中获取数据,在不改动应用程序其他部分的情况下实现需求,可以使用Layer Diagram和Layer Validation来保证开发代码不会违反这一设计。

  我们可以不对接口的具体实现做任何设置,而仅仅依赖于接口本身。这是一个相当普遍的设计模式,但是在现实应用中很容易被违反。只要一行错误的代码就会破坏这个模式,从而在建立模块间出现了不必要的依赖关系(通常使用控制反转(IoC)来解决这个问题)。

  ⑨创建Layer Diagram。可以创建一个Layer Diagram来可视化地描述在架构中想要维护的约束关系。单击主菜单的Architecture|New Diagram命令,选择“Layer Diagram”命令,并将层图命名为“FirstLayerDiagram.layerdiagram”,在弹出的对话框中,将工程命名为“FirstModelingProject”。

  ⑩塑模范本,将代码映射到层上。在Layer Diagram Designer中,从工具箱中拖曳出三个Layer工具到设计平面上,分别由上至下指定层的名称为Client、Interface、Implementation,代表应用程序、工作接口和方法。表示的是Client Logic层依赖于Interfaces层,Implementation层同样依赖于Interfaces层。但是Client Logic层和Implementation层之间没有依赖关系,如图7所示。

图7  创建映射

  如上图所示,然后建立各个层次之间的相互关系。从工具箱中选择Dependency工具,在Solution Explorer中,选中Client工程并将它拖曳到Layer Diagram上的Client Logic层上,代表Client层会依赖Interface层。这时出现了一个由Client指向Interface的箭头链接。将Interfaces工程拖到Interfaces层上;最后,将Implementation工程拖到Implementation层上,代表Implementation层会依赖Interface层;在层右上角的数字“1”表示该层已经和一个工程相关联。

  如果选中Client Logic、Interfaces和Implementation层,再打开Layer Explorer,就可以看到和当前层关联的项目,这里是Client.exe、Interfaces.dll和Implementation.dll,然后就可以用这张图来对代码进行约束与验证,如图8所示。 

图8  进行架构验证

  如上图所示,进行架构验证。用鼠标右键单击Layer Diagram的任何位置,选择“Validate Architecture”命令,进行验证。

  验证架构(Validate Architecture):可以检查出我们的程序是否破坏了层次图中的依赖关系,如果我们的程序中的CaryLayer项目中的程序调用了Common项目中的类等于就违反了以前设计好的层次图,在验证架构的时候就会失败。

  依赖关系(Generate Dependencies):可以根据我们程序中的调用关系生成层的依赖关系。

  错误列表。命令执行完成后会看到“Error List”窗口中有三条错误信息,同时指示错误发生的区域。检视一下错误内容,会发现我们要求的层次依赖关系被破坏了。这是因为Client工程中的Program.cs直接使用了Implementation工程中定义的类型。而在刚才创建的图中,这种依赖关系是错误的,如图3错误列表提示。

  修正代码,解决错误问题。

  打开Program.cs文件,需要确保只使用Interfaces工程中定义的类型,而不能直接使用Implementation工程中定义的类型。我们需要在不产生直接依赖关系的情况下创建实现IDataRetriever接口的对象。

  解决方法是使用Factory模式,利用Factory建立以接口为主的方法。当以后要传回的信息接收器是针对不同的信息来源进行处理的,只要调整Factory方法传回对应的接收器即可,原本的应用程序不用改动,因为它都是通过接口决定作业的,只要实做了同样接口的类都可以套用,从而增加了程序的弹性和维护能力。使用工厂(Factory)模式来解决这个问题的步骤如下:

  在Solution Explorer中展开Creators工程,将Class1.cs重命名为TypeCreator.cs。

  向Creators工程中添加对Implementation和“Interfaces”工程的引用(Creators工程现在依赖于Implementation和Interfaces工程)。

  打开TypeCreators.cs,向其中添加一个静态方法,该方法返回一个IDataRetriever的对象。

代码参考如下所示:

 
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Implementation;
using Interfaces;

namespace Creators
{
public class TypeCreator
{
public static IDataRetriever CreateDataRetriever()
{
return new DataRetriever();
}
}
}

  在Client工程中,移除对Implementation工程的引用,添加对Creators工程的引用。

  修改Program.cs,使用刚才新加的方法来创建对象。代码参考如下所示:

 
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Interfaces;
using Creators;

namespace Client
{
class Program
{
static void Main( string [] args)
{
IDataRetriever dr
= new TypeCreator.CreateDataRetriever();
IData data
= dr.Data;
}
}
}

  修正代码,解决错误问题。

  重新编译Solution,并重新打开FirstLayerDiagram,用鼠标右键单击,在菜单中执行“Validate Architecture”命令。这样我们就不是直接通过实做的类进行信息的存取,而是经由Factory取得符合接口定义的内容。再做一次层验证,我们会看到所有的错误都消失了。

  总结:通过使用Visual Studio 2010层关系设计架构,我们就可以在开始阶段通过层关系图来进行逻辑设计,并努力执行设计方案,保证开发阶段与设计不偏离,通过自动化(例如门控签入)进行强制执行,使团队人员的代码不漂移出架构,从而避免“漂移”发生。另外,采用Layer Diagram来验证代码架构的方法,大型项目也可以通过相同的方式进行验证。这包括如何将代码映射到层上,以及如何通过手动的方式来验证代码是否遵守定义的约束关系,也可以在编译代码的过程中自动地进行验证。

  【相关文章】:用好Visual Studio 2010进行层架构设计

目录
相关文章
|
6月前
|
API C++ Windows
Visual C++运行库、.NET Framework和DirectX运行库的作用及常见问题解决方案,涵盖MSVCP140.dll丢失、0xc000007b错误等典型故障的修复方法
本文介绍Visual C++运行库、.NET Framework和DirectX运行库的作用及常见问题解决方案,涵盖MSVCP140.dll丢失、0xc000007b错误等典型故障的修复方法,提供官方下载链接与系统修复工具使用指南。
1535 2
|
6月前
|
存储 缓存 安全
某鱼电商接口架构深度剖析:从稳定性到高性能的技术密码
某鱼电商接口架构揭秘:分层解耦、安全加固、性能优化三维设计,实现200ms内响应、故障率低于0.1%。详解三层架构、多引擎存储、异步发布、WebSocket通信与全链路防护,助力开发者突破电商接口“三难”困境。
|
6月前
|
人工智能 自然语言处理 安全
AI助教系统:基于大模型与智能体架构的新一代教育技术引擎
AI助教系统融合大语言模型、教育知识图谱、多模态交互与智能体架构,实现精准学情诊断、个性化辅导与主动教学。支持图文语音输入,本地化部署保障隐私,重构“教、学、评、辅”全链路,推动因材施教落地,助力教育数字化转型。(238字)
1132 23
|
6月前
|
Java Linux 虚拟化
【Docker】(1)Docker的概述与架构,手把手带你安装Docker,云原生路上不可缺少的一门技术!
1. Docker简介 1.1 Docker是什么 为什么docker会出现? 假定您在开发一款平台项目,您的开发环境具有特定的配置。其他开发人员身处的环境配置也各有不同。 您正在开发的应用依赖于您当前的配置且还要依赖于某些配置文件。 您的企业还拥有标准化的测试和生产环境,且具有自身的配置和一系列支持文件。 **要求:**希望尽可能多在本地模拟这些环境而不产生重新创建服务器环境的开销 问题: 要如何确保应用能够在这些环境中运行和通过质量检测? 在部署过程中不出现令人头疼的版本、配置问题 无需重新编写代码和进行故障修复
589 2
|
7月前
|
Cloud Native API 开发者
Gemini 2.5 Flash 技术拆解:从 MoE 架构到阿里云生态落地指南
2025年9月,谷歌Gemini 2.5 Flash发布,性能提升5%、成本降24%,引发行业关注。其MoE架构、百万上下文与“思考”范式,助力阿里云开发者高效构建云原生应用。本文解析技术内核,结合汽车、物流等案例,提供落地指南与避坑建议,展望大模型与流计算融合前景。
843 6
|
6月前
|
存储 人工智能 搜索推荐
拔俗AI助教系统:基于大模型与智能体架构的新一代教育技术引擎
AI助教融合大语言模型、教育知识图谱、多模态感知与智能体技术,重构“教、学、评、辅”全链路。通过微调LLM、精准诊断错因、多模态交互与自主任务规划,实现个性化教学。轻量化部署与隐私保护设计保障落地安全,未来将向情感感知与教育深度协同演进。(238字)
786 0
|
6月前
|
Cloud Native Serverless API
微服务架构实战指南:从单体应用到云原生的蜕变之路
🌟蒋星熠Jaxonic,代码为舟的星际旅人。深耕微服务架构,擅以DDD拆分服务、构建高可用通信与治理体系。分享从单体到云原生的实战经验,探索技术演进的无限可能。
微服务架构实战指南:从单体应用到云原生的蜕变之路
|
弹性计算 API 持续交付
后端服务架构的微服务化转型
本文旨在探讨后端服务从单体架构向微服务架构转型的过程,分析微服务架构的优势和面临的挑战。文章首先介绍单体架构的局限性,然后详细阐述微服务架构的核心概念及其在现代软件开发中的应用。通过对比两种架构,指出微服务化转型的必要性和实施策略。最后,讨论了微服务架构实施过程中可能遇到的问题及解决方案。