La esencia de mi pregunta es cómo componer estos objetos (ver a continuación) de manera sensata con MVC3 y Ninject (aunque no estoy seguro de que DI deba desempeñar un papel en la solución) No puedo revelar los detalles reales de mi proyecto, pero aquí hay una aproximación que ilustra el problema/pregunta. ¡Se agradecen las respuestas en VB o C#!Componiendo objetos polimórficos en el proyecto ASP.NET MVC3
Tengo varios productos diferentes con propiedades que varían ampliamente pero todos ellos necesitan estar representados en un catálogo. Cada clase de producto tiene una tabla correspondiente en mi base de datos. Una entrada de catálogo tiene un puñado de propiedades específicas para ser una entrada de catálogo y, en consecuencia, tienen su propia tabla. He definido una interfaz para las entradas de catálogo con la intención de que llamar a la propiedad DescriptionText me proporcione resultados muy diferentes en función del tipo concreto subyacente.
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
Dado que el DescriptionText es una preocupación capa de presentación no quiero para implementar la interfaz ICatalogEntry en mis clases de productos. En cambio, quiero delegar eso en algún tipo de formateador.
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
En un controlador de algún lugar habrá un código como éste:
Dim entries As List(Of ICatalogEntry)
= catalogService.CurrentCatalog(DateTime.Now)
En una vista en algún lugar habrá un código como éste:
<ul>
@For Each entry As ICatalogEntry In Model.Catalog
@<li>@entry.DescriptionText</li>
Next
</ul>
Así que la pregunta es lo que hace el constructores parecen? Cómo configurarlo para que los objetos apropiados sean instanciados en los lugares correctos. Parece que los medicamentos genéricos o tal vez DI puede ayudar con esto, pero parece que estoy teniendo un bloqueo mental. La única idea que he llegado con es añadir una propiedad ProductType a ICatalogEntry y luego aplicar una fábrica de la siguiente manera:
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
en mi humilde opinión, no estoy realmente recibiendo ningún olor fuera de este código aparte de tener que cambiar el fábrica para cada nueva clase de producto que se presente. Sin embargo, mi instinto me dice que esta es la forma antigua de hacer las cosas y que hoy DI y/o genéricos pueden hacerlo mejor. Sugerencias sobre cómo manejar esto son muy apreciadas (como son sugerencias sobre un mejor título ...)
¿La resolución personalizada maneja el hecho de que más de una clase se asigna a la misma interfaz? Eso es lo que me empuja a la clase de fábrica en mi pregunta y eso es lo que más me incomoda y no tengo muy claro cómo deshacerme de él. – schmidlop
Bien, ahora que leí el enlace que proporcioné, he llegado a la conclusión de que debo esperar razonablemente que mi contenedor DI (Ninject) tenga alguna respuesta para este escenario. Además, parece que sí y necesito un enlace contextual https://github.com/ninject/ninject/wiki/Contextual-Binding y probablemente también necesite esto: https://github.com/ninject/ninject.extensions. fábrica/wiki – schmidlop
Sí, eso realmente debería resolver su problema. En su inicialización de ninject, debería poder cargar desde un archivo de recursos. –