我想就以下情况下使用的最佳方法提出一些建议.
我将有一个Windows应用程序和一个Web应用程序(表示层),它们都将访问公共业务层。业务层将查看配置文件以查找dll (数据层)的名称,它将在运行时创建引用(这是最好的方法吗?)
在运行时创建数据访问层引用的原因是,应用程序将与不同的第三方计费系统进行接口,具体取决于客户端使用的内容。因此,我将有一个单独的数据访问层,以支持每个会计系统。这些可以是单独的安装项目,每个客户端将使用其中一个或另一个,它们不需要在两者之间切换。
项目:
MyCompany.Common.dll -包含接口,所有其他项目都有对此的引用。
MyCompany.Windows.dll - Windows项目,参考MyCompany.Business.dll
MyCompany.Web.dll -网站项目,参考MyCompany.Business.dll
MyCompany.Busniess.dll -业务层,引用MyCompany.Data.* (在运行时)
会计系统的数据层
项目MyCompany.Common.dll将包含所有接口,每个项目都将引用这个接口。
Public Interface ICompany
ReadOnly Property Id() as Integer
Property Name() as String
Sub Save()
End Interface
Public Interface ICompanyFactory
Function CreateCompany() as ICompany
End Interface
项目MyCompany.Data.AccountingSys1.dll和MyCompany.Data.AccountingSys2.dll将包含如下类:
Public Class Company
Implements ICompany
Protected _id As Integer
Protected _name As String
Public ReadOnly Property Id As Integer Implements MyCompany.Common.ICompany.Id
Get
Return _id
End Get
End Property
Public Property Name As String Implements MyCompany.Common.ICompany.Name
Get
Return _name
End Get
Set(ByVal value as String)
_name = value
End Set
End Property
Public Sub Save() Implements MyCompany.Common.ICompany.Save
Throw New NotImplementedException()
End Sub
End Class
Public Class CompanyFactory
Implements ICompanyFactory
Public Function CreateCompany() As ICompany Implements MyCompany.Common.ICompanyFactory.CreateCompany
Return New Company()
End Function
End Class
项目MyCompany.Business.dll将提供业务规则并从数据层检索数据:
Public Class Companies
Public Shared Function CreateCompany() As ICompany
Dim factory as New MyCompany.Data.CompanyFactory
Return factory.CreateCompany()
End Function
End Class
如有任何意见/建议,将不胜感激。
发布于 2010-03-17 17:13:47
几点意见。
我将避免使用MyCompany.Common.dll
程序集。这些程序通常会被各种不相关的东西填满,然后被更改,通常需要对所有程序集进行重新构建。
我会用应用程序名和公司名称命名您的程序集。MyCompany.MyApplication.Business.dll
比MyCompany.Business.dll
更可取。然后,可以更容易地将应用程序划分为子部分,并从多个应用程序重用代码。
对于您将要拥有的每种类型的实现程序集,最好有单独的契约程序集。就你的情况而言,我建议如下:
MyCompany.MyApplication.Windows-Contract.dll
MyCompany.MyApplication.Windows.dll
MyCompany.MyApplication.Web-Contract.dll
MyCompany.MyApplication.Web.dll
MyCompany.MyApplication.Business-Contract.dll
MyCompany.MyApplication.Business.dll
MyCompany.MyApplication.Data-Contract.dll
MyCompany.MyApplication.Data.AccountingSys1.dll
MyCompany.MyApplication.Data.AccountingSys2.dll
从您的描述中可以看出,AccountingSys1
和AccountingSys2
程序集共享一个公共契约,因此只有两个实现程序集的一个契约程序集。
契约程序集应该表示您的设计,而不是表示您的实现,并且只因为设计更改而进行更改。您应该避免使用任何“重要”代码(以避免bug),并且应该将代码限制为接口、枚举、异常、属性、事件args和结构--所有这些代码都没有“重要”代码。
在设置程序集引用时,应确保程序集只引用合同程序集,如下所示:
Data.AccountingSys1
Data-Contract
Data.AccountingSys2
Data-Contract
Business
Business-Contract
Data-Contract
Windows
Windows-Contract
Business-Contract
Data-Contract (maybe)
Web
Web-Contract
Business-Contract
Data-Contract (maybe)
因此,实现程序集永远不依赖于其他实现程序集。当实现更改时,您只能重新生成一个程序集。
此规则的例外情况是在创建继承层次结构时。例如,您可以创建一个*.Data.AccountingSys.dll
来为两个特定的会计系统程序集定义基类。
如果您可以遵循上述所有内容,那么您将需要实现某种依赖注入方法,以便能够从契约程序集中的接口创建对象的实例。您可以使用现有的DI框架,也可以创建包含工厂方法的第三组*-Factory.dll
程序集。
这种结构的另一个好处是,单元测试要简单得多,可以基于契约而不是实现,从而帮助您编写干净、可测试的代码。
这可能看起来像很多程序集,但阻止代码创建恶劣的依赖关系所带来的好处将大大减少项目变得过于复杂的可能性,并将有助于提高您的项目的质量。现在稍微痛一下,以后就会消除那么多的痛苦。
发布于 2010-03-17 16:02:31
你的一般做法是合理的:)
您可以考虑将所有接口放在一个独立的程序集(dll)中(严格地说,接口位于业务逻辑和数据访问实现之间--它们应该是唯一能够访问接口的东西),但在可能不是什么大问题的大方案中。
就我个人而言,我有一个共享的工厂方法,它返回一个对象,并在使用时适当地转换它。
发布于 2010-03-17 16:11:12
这是一个很好的方法!我已经在我们的一个工作系统中使用了它,它被证明是可靠的,可以维护,并允许我们在需要时快速添加额外的接口(例如,当我们需要与我们收购的公司的另一个会计系统接口时)。
https://stackoverflow.com/questions/2466293
复制