我的问题的本质是如何使用 MVC3 和 Ninject 以合理的方式组合这些对象(见下文)(尽管我不确定 DI 是否应该在解决方案中发挥作用)。我不能透露我的项目的真实细节,但这里有一个近似值来说明问题/问题。VB 或 C# 中的答案表示赞赏!
我有几种不同的产品,它们的特性各不相同,但它们都需要在目录中表示。每个产品类在我的数据库中都有一个对应的表。目录条目具有一些特定于作为目录条目的属性,因此具有自己的表。我已经为目录条目定义了一个接口,其意图是调用 DescriptionText 属性将根据底层的具体类型给我非常不同的结果。
Public Class Clothing
Property Identity as Int64
Property AvailableSizes As List(Of String)
Property AvailableColor As List(Of String)
End Class
Public Class Fasteners
Property Identity as Int64
Property AvailableSizes As List(Of String)
Property AvailableFinishes As List(Of String)
Property IsMetric As Boolean
End Class
Public Interface ICatalogEntry
Property ProductId as Int64
Property PublishedOn As DateTime
Property DescriptionText As String
End Interface
鉴于 DescriptionText 是一个表示层问题,我不想在我的产品类中实现 IATAlogEntry 接口。相反,我想将其委托给某种格式化程序。
Public Interface ICatalogEntryFormatter
Property DescriptionText As String
End Interface
Public Class ClothingCatalogEntryFormatter
Implements ICatalogEntryFormatter
Property DescriptionText As String
End Class
Public Class FastenerCatalogEntryFormatter
Implements ICatalogEntryFormatter
Property DescriptionText As String
End Class
在某处的控制器中会有这样的代码:
Dim entries As List(Of ICatalogEntry)
= catalogService.CurrentCatalog(DateTime.Now)
在某处的视图中会有这样的代码:
<ul>
@For Each entry As ICatalogEntry In Model.Catalog
@<li>@entry.DescriptionText</li>
Next
</ul>
所以问题是构造函数是什么样的?如何设置它以便在正确的位置实例化适当的对象。似乎泛型或 DI 可以帮助解决这个问题,但我似乎有一个心理障碍。我想出的唯一想法是将 ProductType 属性添加到 IATAlogEntry ,然后实现这样的工厂:
Public Class CatalogEntryFactory
Public Function Create(catEntry as ICatalogEntry) As ICatalogEntry
Select Case catEntry.ProductType
Case "Clothing"
Dim clothingProduct = clothingService.Get(catEntry.ProductId)
Dim clothingEntry = New ClothingCatalogEntry(clothingProduct)
Return result
Case "Fastener"
Dim fastenerProduct = fastenerService.Get(catEntry.ProductId)
Dim fastenerEntry = New FastenerCatalogEntry(fastenerProduct)
fastenerEntry.Formatter = New FastenerCatalogEntryFormatter
Return fastenerEntry
...
End Function
End Class
Public ClothingCatalogEntry
Public Sub New (product As ClothingProduct)
Me.Formatter = New ClothingCatalogEntryFormatter(product)
End Sub
Property DescriptionText As String
Get
Return Me.Formatter.DescriptionText
End Get
End Property
End Class
...FastenerCatalogEntry is omitted but you get the idea...
Public Class CatalogService
Public Function CurrentCatalog(currentDate as DateTime)
Dim theCatalog As List(Of ICatalogEntry)
= Me.repository.GetCatalog(currentDate)
Dim theResult As New List(Of ICatalogEntry)
For Each entry As ICataLogEntry In theCatalog
theResult.Add(factory.Create(entry))
Next
Return theResult
End Function
End Class
恕我直言,除了必须为每个出现的新产品类别更改工厂外,我并没有真正从这段代码中得到任何气味。然而,我的直觉告诉我这是旧的做事方式,现在 DI 和/或泛型可以做得更好。非常感谢有关如何处理此问题的建议(以及有关更好标题的建议......)