6

में बहुलक पॉलीमोर्फिक ऑब्जेक्ट्स का निर्माण करना मेरे प्रश्न का सार यह है कि एमवीसी 3 और निनजेक्ट के साथ एक समझदार तरीके से इन वस्तुओं को कैसे लिखें (नीचे देखें) (हालांकि मुझे यकीन नहीं है कि डीआई को समाधान में भूमिका निभाई जानी चाहिए)। मैं अपने प्रोजेक्ट के वास्तविक विवरण का खुलासा नहीं कर सकता लेकिन यहां एक अनुमान है जो इस मुद्दे/प्रश्न को दर्शाता है। या तो वीबी या सी # में जवाब की सराहना की जाती है!एएसपी.नेट एमवीसी 3 प्रोजेक्ट

मेरे पास व्यापक रूप से भिन्न गुणों के साथ कई अलग-अलग उत्पाद हैं, फिर भी उनमें से सभी को एक सूची में प्रतिनिधित्व करने की आवश्यकता है। प्रत्येक उत्पाद वर्ग में मेरे डेटाबेस में एक संबंधित तालिका है। एक कैटलॉग एंट्री में कैटलॉग एंट्री होने के लिए विशिष्ट गुणों का एक मुट्ठी भर होता है और इसके परिणामस्वरूप उनकी अपनी तालिका होती है। मैंने सूची प्रविष्टियों के लिए एक इंटरफ़ेस परिभाषित किया है, जिसमें विवरण टेक्स्ट को सम्मिलित करने के इरादे से अंतर्निहित ठोस प्रकार के आधार पर मुझे बहुत अलग परिणाम मिलेंगे।

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 इसके साथ मदद कर सकता है लेकिन मुझे मानसिक ब्लॉक होने लगता है। केवल विचार मैं ले कर आए हैं ICatalogEntry करने के लिए एक ProductType संपत्ति जोड़ने के लिए और फिर इस तरह एक कारखाने को लागू है:

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, मैं वास्तव में किसी भी हो रही है नहीं कर रहा हूँ अन्य इस कोड को बंद बदबू आ रही है बदलने के लिए की तुलना में साथ आने वाले हर नए उत्पाद वर्ग के लिए कारखाना। फिर भी, मेरा आंत कहता है कि यह चीजों को करने का पुराना तरीका है और आजकल डीआई और/या जेनेरिक यह बेहतर कर सकते हैं। इसे संभालने के तरीकों पर सुझावों की बहुत सराहना की जाती है (जैसा कि बेहतर शीर्षक पर सुझाव हैं ...)

उत्तर

1

तो कुछ छोटे बदलाव करने के कारण मुझे निनजेक्ट फैक्ट्री एक्सटेंशन का उपयोग करके काम करने के लिए मिला। सबसे बड़ा परिवर्तन यह है कि यदि मेरी वस्तुएं वास्तव में कपड़े हैं तो मेरे इकाइयों में किसी भी प्रकार (कपड़े या फास्टनर मेरे उत्कीर्ण उदाहरण में) प्रदर्शित करने के लिए पर्याप्त जानकारी होती है, तो फास्टनर विशिष्ट गुण शून्य और इसके विपरीत होंगे।

Public Interface IDescribable 
    ReadOnly Property DescriptionText As String 
End Interface 

Public Enum ProductType 
    CLOTHING 
    FASTENER 
End Enum 

Public Interface ICatalogEntry 
    Inherits IDescribable 
    ReadOnly Property ProductId As Int64 
    ReadOnly Property PublishedOn As DateTime 
    ReadOnly Property ProductType As ProductType 
End Interface 

Public Class CatalogEntryEntity 
    Public Property ProductId As Long 
    Public Property ProductType As ProductType 
    Public Property PublishedOn As Date 
    Public Property DescriptionText As String 
    Public Property Color As String 
    Public Property Finish As String 
    Public Property IsMetric As Boolean 
End Class 

फिर जगह में इस के साथ मैं इस प्रकार मेरी सूची सेवा को परिभाषित कर सकते हैं:

Public Class CatalogService 
    Private ReadOnly _factory As ICatalogEntryFactory 
    Private ReadOnly _repository As CatalogRepository 

    Public Sub New(entryFactory As ICatalogEntryFactory, repository As CatalogRepository) 
     Me._factory = entryFactory 
     Me._repository = repository 
    End Sub 

    Public Function CurrentCatalog(currentDate As DateTime) As List(Of ICatalogEntry) 
     Dim items = Me._repository.GetCatalog() 
     Return (From item In items Select _factory.Create(item.ProductType.ToString(), item)).ToList() 
    End Function 
End Class 

Public Interface ICatalogEntryFactory 
    Function Create(bindingName As String, entity As CatalogEntryEntity) As ICatalogEntry 
End Interface 

Ninject कारखाने प्रदान करेगा यह सोचते हैं मैं सेटअप बाइंडिंग इस तरह (जो बेहतरीन है!):

theKernel.Bind(Of ICatalogEntry)().To(Of ClothingCatalogEntry)().Named("CLOTHING") 
theKernel.Bind(Of ICatalogEntry)().To(Of FastenerCatalogEntry)().Named("FASTENER") 
theKernel.Bind(Of ICatalogEntryFactory)().ToFactory(Function() New UseFirstParameterAsNameInstanceProvider()) 

मैंने ब्रेवटी के लिए FastenerCatalogEntry को छोड़ दिया है; ClothingCatalogEntry इस तरह है:

Public Class ClothingCatalogEntry 
    Public Sub New(ByVal entity As CatalogEntryEntity) 
... 

यह this post है कि मुझे सबसे अधिक मदद की इस यह पता लगाने की थी। मैंने वर्कफास्ट पैरामीटर एएसनाम इंस्टेंसप्रोवाइडर का उपयोग बिल्कुल दिखाया जैसा कि दिखाया गया है।

1

मुझे दृश्य के लिए मॉडल पर डिफ़ॉल्ट कन्स्ट्रक्टर का उपयोग करना पसंद है और उन्हें Automapper के माध्यम से पॉप्युलेट करना है।

मैं इस तरह एक दृश्य मॉडल होगा:

public interface IHasDescription 
{ 
    public string DescriptionText { get; set; } 
} 

public class ViewModelType : IHasDescription 
{ 
    [DisplayName("This will be rendered in the view")] 
    public string SomeText { get; set; } 

    public string DescriptionText { get; set; } 
} 

और मैं इस तरह दाल से एक मॉडल है:

public class DALModelType 
{ 
    public string SomeText { get; set; } 
} 

तो आप अपने नियंत्रक में कुछ इस तरह है:

var dalModel = someRepository.GetAll(); 
var viewModel = Mapper.Map<DALModelType, ViewModelType>(dalModel); 

और आपके पास कुछ फ़ाइल में ऑटोमैपर सेटअप कोड है। इस तरह आपके पास एकाधिक विधियों/नियंत्रकों की बजाय एक स्थान पर केवल रूपांतरण कोड है। आपके पास custom resolver है जो निर्भरता इंजेक्शन का उपयोग करता है (इसके बजाय() => नया कस्टम रीसोलवर()) और यह प्रदर्शन टेक्स्ट प्राप्त करने के लिए आपका तर्क रखेगा।

Mapper.CreateMap<IHasDescription, ViewModelType>() 
    .ForMember(dest => dest.DescriptionText, 
       opt => opt.ResolveUsing<CustomResolver>().ConstructedBy(() => new CustomResolver())); 

सुनिश्चित नहीं हैं कि अगर यह अपने कार्यप्रवाह के साथ काम करता है, लेकिन यह आप क्या चाहते हैं आप प्राप्त करने में सक्षम होना चाहिए।

+0

तो कस्टम रिज़ॉल्यूवर इस तथ्य को संभालता है कि एक से अधिक कक्षा एक ही इंटरफ़ेस के मानचित्र हैं? यही कारण है कि मुझे अपने प्रश्न में कारखाने वर्ग में धक्का दे रहा है और यही वह है जो मैं सबसे ज्यादा असहज हूं और पूरी तरह अस्पष्ट हूं कि कैसे छुटकारा पाएं। – schmidlop

+0

ठीक है, अब मैंने आपके द्वारा प्रदान किए गए लिंक को पढ़ा है, मैंने निष्कर्ष निकाला है कि मुझे उचित रूप से मेरे डी कंटेनर (निनजेक्ट) को इस परिदृश्य के लिए कुछ जवाब देने की उम्मीद करनी चाहिए। इसके अलावा ऐसा लगता है कि यह करता है और मुझे प्रासंगिक बाध्यकारी https://github.com/ninject/ninject/wiki/Contextual- बाइंडिंग की आवश्यकता है और मुझे शायद इसकी भी आवश्यकता है: https://github.com/ninject/ninject.extensions। कारखाना/विकी – schmidlop

+0

हाँ, यह वास्तव में आपकी समस्या का समाधान करना चाहिए। आपके निंजा प्रारंभ में आपको संसाधन फ़ाइल से लोड करने में सक्षम होना चाहिए। –

संबंधित मुद्दे