L'essenza della mia domanda è come comporre questi oggetti (vedi sotto) in modo sensato con MVC3 e Ninject (anche se non sono sicuro che DI dovrebbe svolgere un ruolo nella soluzione). Non posso rivelare i dettagli reali del mio progetto ma qui è un'approssimazione che illustra il problema/domanda. Le risposte in VB o C# sono apprezzate!Composizione di oggetti polimorfici nel progetto ASP.NET MVC3
Ho diversi prodotti con proprietà molto diverse, ma tutti devono essere rappresentati in un catalogo. Ogni classe di prodotto ha una tabella corrispondente nel mio database. Una voce di catalogo ha una manciata di proprietà specifiche per essere una voce di catalogo e di conseguenza dispone di una propria tabella. Ho definito un'interfaccia per le voci del catalogo con l'intento che chiamare la proprietà DescriptionText mi darà risultati molto diversi in base al tipo concreto sottostante.
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
Dato che la DescriptionText è una preoccupazione presentazione strato Non voglio per implementare l'interfaccia ICatalogEntry nelle mie classi di prodotto. Invece voglio delegarlo a qualche tipo di formattatore.
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
In un controller da qualche parte ci sarà il codice come questo:
Dim entries As List(Of ICatalogEntry)
= catalogService.CurrentCatalog(DateTime.Now)
In una vista da qualche parte ci sarà il codice come questo:
<ul>
@For Each entry As ICatalogEntry In Model.Catalog
@<li>@entry.DescriptionText</li>
Next
</ul>
Quindi la domanda è che cosa fare il assomigliano costruttori? Come impostarlo in modo che gli oggetti appropriati vengano istanziati nei posti giusti. Sembra che i farmaci generici o forse DI possano aiutare in questo, ma mi sembra di avere un blocco mentale. L'unica idea che è venuta in mente è quello di aggiungere una proprietà ProductType per ICatalogEntry e quindi implementare una fabbrica come questa:
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
IMHO, non sto veramente ottenere qualsiasi odori fuori questo codice diverso da dover cambiare la fabbrica per ogni nuova classe di prodotti che arriva. Eppure, il mio istinto dice che questo è il vecchio modo di fare le cose e oggi DI e/o generici possono farlo meglio. Suggerimenti su come gestirlo sono molto apprezzati (come i suggerimenti su un titolo migliore ...)
Quindi il resolver personalizzato gestisce il fatto che più di una classe esegue il mapping sulla stessa interfaccia? Questo è ciò che mi spinge alla classe di fabbrica nella mia domanda ed è quello che mi imbarazza di più e del tutto oscuro come liberarmi di. – schmidlop
Ok, ora che ho letto il link che hai fornito, ho concluso che dovrei ragionevolmente aspettarmi che il mio contenitore DI (Ninject) abbia una risposta per questo scenario. Inoltre sembra che lo faccia e ho bisogno di un binding contestuale https://github.com/ninject/ninject/wiki/Contextual-Binding e probabilmente ho bisogno anche di questo: https://github.com/ninject/ninject.extensions. factory/wiki – schmidlop
Sì, questo dovrebbe effettivamente risolvere il tuo problema. Nella tua inizializzazione ninject dovresti essere in grado di caricare da un file di risorse. –