ASP.NET插件架构:引用其他模块

时间:2010-11-08 11:08:52

标签: asp.net design-patterns architecture

我们目前正在将ASP Intranet迁移到.NET,我们开始在一个ASP.NET网站上开发这个Intranet。但是,这引发了一些关于Visual Studio的问题(性能,编译时间......)。

因为我们的Intranet基本上存在模块,所以我们希望在Visual Studio的子项目中分离我们的项目(每个模块都是一个子项目)。 这也引起了一些问题,因为模块相互引用。 模块X 使用模块Y ,反之亦然......(循环依赖)。

开发此类Intranet的最佳方式是什么?
我会举一个例子,因为很难解释。

我们有一个维护员工的模块。每个员工都有不同的文件(合同,员工创建的文件......) 我们Intranet内的所有文档都由文档模块维护。

员工模块需要引用文档模块
如果将来我需要在 document-module 中引用 employee-module 该怎么办?

解决这个问题的最佳方法是什么?

2 个答案:

答案 0 :(得分:1)

听起来我觉得你有两个问题。

首先,您需要将系统的业务导向功能分解为有凝聚力的部分;在面向对象设计方面,您应该使用一些原则来指导您的思考:

这个想法是那些密切相关的事情,如果一个人需要改变,他们都可能需要改变。

不要试图让组件做得多。

我认为你还需要更仔细地查看你的依赖结构 - 一旦你开始获得循环引用,它可能表明你没有正确分开各种“事物”。也许您需要更多地了解问题域?这是一个常见的问题 - 嗯,不仅仅是设计复杂系统的一部分问题。

一旦你解决了这个问题,它将使第二部分变得更加容易:系统架构和设计。

幸运的是,插件上已有很多现有材料,请尝试按标签搜索,例如:

修改

  
    

资产在与员工不同的模块中定义。但是Assets-class定义了一个属性'AssignedTo',它属于'Employee'类型。我一直在试图断开这两个

  

这有两个部分,您可能希望同时使用两者:

  • 使用包含系统所有部分可以共享的简单数据结构的公共层。
  • 使用界面。

公共图层/ POCO

POCO代表“普通旧CLR对象”,其思想是POCO是一种简单的数据结构,可用于在层之间交换信息 - 或者在您需要保持松散耦合的模块之间。 POCO不包含任何业务逻辑。像对待String或DateTime类型一样对待它们。

因此,资产和员工类不是引用彼此,而是引用POCO。

这个想法是在一个公共程序集中定义它们,其他应用程序/模块可以引用它们。定义这些的程序集需要没有不必要的依赖 - 这应该很容易。

<强>接口

这几乎是一样的,但是你不是指一个具体的对象(比如POCO)而是指一个接口。这些接口的定义方式与上述POCO类似(通用程序集,无依赖关系)。

然后,您可以使用Factory在运行时加载具体对象。这基本上是依赖倒置。

因此,Asset和Employee类不是引用彼此,而是引用接口,并在运行时实例化具体实现。

本文可能对以上两个选项都有帮助:An Introduction to Dependency Inversion

修改

  
    

我有以下方法GetAsset(int assetID);在此方法中,填写属性asset.AssignedTo(类型IAssignable)。如何正确分配?

  

这取决于逻辑的位置,以及您希望如何构建事物。

如果你有一个业务逻辑(BL)层 - 主要是一个全面的域模型(DM)(其中资产和员工都是成员),那么很可能是资产和成员会彼此了解,当你做了一个填充资产的电话,你可能也得到了合适的员工数据。在这种情况下,BL / DM要求数据 - 而不是孤立的资产和成员类。

在这种情况下,您的“模块”将是在上述BL / DM之上构建的另一层。

我对此的变化是,在GetAsset()内部,您只能获得资产数据,之后您可以单独获取员工数据。无论您如何松散地处理事物,都必须某些点,您可以在其中定义Asset和Employee之间的连接,即使它只是在数据中。

这表明某种寄存器模式,即定义“连接”的地方,并且只要您处理“IAssignable”类型,您就知道需要检查寄存器是否有任何可能的分配。

答案 1 :(得分:0)

我会考虑为您的插件创建接口,以便您可以添加新模块,只要它们遵循接口规范,您的项目就可以在不明确了解它们的情况下调用它们。< / p>

我们使用它来为我们的应用程序创建插件。每个插件都封装在实现特定接口的用户控件中,然后我们随时添加新模块,并且因为它们是用户控件,我们可以在数据库中存储控件的路径,并使用加载控件来加载它们,我们使用界面来操作它们,加载它们的页面不需要知道它们的作用。