Суть моего вопроса состоит в том, как скомпоновать эти объекты (см. Ниже) с MVC3 и Ninject (хотя я не уверен, что DI должен играть роль в решении). Я не могу раскрывать реальные детали моего проекта, но здесь приведено приближение, которое иллюстрирует проблему/вопрос. Ответы в VB или C# оцениваются!Составление полиморфных объектов в проекте ASP.NET MVC3
У меня есть несколько различных продуктов с разнообразными свойствами, но все они должны быть представлены в каталоге. Каждый класс продукта имеет соответствующую таблицу в моей базе данных. В записи каталога есть несколько свойств, характерных для входа в каталог, и, следовательно, их таблица. Я определил интерфейс для записей в каталоге с намерением, что вызов свойства 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 является уровень представления беспокойство, которое я не хочу, чтобы реализовать интерфейс ICatalogEntry в моих классах продукции. Вместо этого я хочу делегировать это формату.
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 в ICatalogEntry, а затем реализовать завод, как это:
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 и/или дженерики могут сделать это лучше. Предложения о том, как с этим справиться, очень ценятся (как и предложения по лучшему названию ...)
Так что пользовательский резольвер обрабатывает тот факт, что более одного класса сопоставляется с одним и тем же интерфейсом? Это то, что подталкивает меня к фабричному классу в моем вопросе, и именно это мне неудобно и совершенно неясно, как избавиться. – schmidlop
Хорошо, теперь, когда я прочитал указанную вами ссылку, я пришел к выводу, что должен разумно ожидать, что мой контейнер DI (Ninject) получит ответ на этот сценарий. Кроме того, похоже, что это так, и мне нужна контекстная привязка https://github.com/ninject/ninject/wiki/Contextual-Binding, и мне это тоже нужно: https://github.com/ninject/ninject.extensions. factory/wiki – schmidlop
Да, это действительно должно решить вашу проблему. В вашей инициализации ninject вы можете загрузить из файла ресурсов. –