मैं अपने WPF आवेदन में निर्माता निर्भरता इंजेक्शन का उपयोग कर रहा है और मैं निम्नलिखित पैटर्न में प्रदर्शन जारी रहे, तो उस पर अन्य लोगों की राय हो और वैकल्पिक समाधान के बारे में सुनना पसंद करेंगे।संग्रह से मॉडलों को उनके व्यू मॉडेल में आपूर्ति करने के लिए मैं कन्स्ट्रक्टर निर्भरता इंजेक्शन का उपयोग कैसे करूं?
लक्ष्य व्यूमोडल्स के पदानुक्रम को मॉडल के समान पदानुक्रम में तारित करना है, ताकि प्रत्येक मॉडल में जानकारी पेश करने की ज़िम्मेदारी अपने स्वयं के व्यू मॉडेल कार्यान्वयन के साथ हो। (पैटर्न भी अन्य परिस्थितियों में ऊपर फसलों लेकिन MVVM एक अच्छा उदाहरण के लिए करना चाहिए।)
यहाँ एक सरल उदाहरण है। यह देखते हुए मैं एक मॉडल आगे मॉडल का एक संग्रह है कि है:
public interface IPerson
{
IEnumerable<IAddress> Addresses { get; }
}
public interface IAddress
{
}
मैं ViewModels में इस पदानुक्रम दर्पण ताकि मैं एक ListBox व्यक्ति ViewModel में एक संग्रह करने के लिए बाध्य (या जो भी) कर सकते हैं करना चाहते हैं:
public interface IPersonViewModel
{
ObservableCollection<IAddressViewModel> Addresses { get; }
void Initialize();
}
public interface IAddressViewModel
{
}
बच्चे ViewModel बच्चे मॉडल से जानकारी पेश करने के लिए की जरूरत है, तो यह निर्माता के माध्यम से इंजेक्शन है:
public class AddressViewModel : IAddressViewModel
{
private readonly IAddress _address;
public AddressViewModel(IAddress address)
{
_address = address;
}
}
सवाल यह है कि, सबसे अच्छा तरीका क्या है संबंधित मॉडल ViewModel को बच्चे मॉडल की आपूर्ति करने के लिए?
उदाहरण छोटा है, लेकिन एक सामान्य वास्तविक मामले में व्यूमोडल्स की अधिक निर्भरताएं होती हैं - जिनमें से प्रत्येक की अपनी निर्भरताएं होती हैं (और इसी तरह)। मैं एकता 1.2 का उपयोग कर रहा हूं (हालांकि मुझे लगता है कि प्रश्न अन्य आईओसी कंटेनरों में प्रासंगिक है), और मैं कैलिबर्न की दृश्य रणनीतियों का उपयोग कर रहा हूं ताकि वे दृश्य दृश्य को उचित रूप से ढूंढ सकें और वायरस कर सकें।
यहाँ मेरे वर्तमान समाधान है:
माता पिता ViewModel प्रत्येक बच्चे मॉडल के लिए एक बच्चे ViewModel बनाने के लिए की जरूरत है, तो यह एक कारखाने विधि अपने निर्माता को जोड़ा गया है जो इसे प्रारंभ के दौरान का उपयोग करता है:
public class PersonViewModel : IPersonViewModel
{
private readonly Func<IAddress, IAddressViewModel> _addressViewModelFactory;
private readonly IPerson _person;
public PersonViewModel(IPerson person,
Func<IAddress, IAddressViewModel> addressViewModelFactory)
{
_addressViewModelFactory = addressViewModelFactory;
_person = person;
Addresses = new ObservableCollection<IAddressViewModel>();
}
public ObservableCollection<IAddressViewModel> Addresses { get; private set; }
public void Initialize()
{
foreach (IAddress address in _person.Addresses)
Addresses.Add(_addressViewModelFactory(address));
}
}
एक कारखाने विधि है कि Func<IAddress, IAddressViewModel>
इंटरफेस को संतुष्ट करता है मुख्य UnityContainer
साथ पंजीकृत है। कारखाने विधि IAddress
निर्भरता कि ViewModel के लिए आवश्यक है रजिस्टर करने के लिए एक बच्चे के कंटेनर का उपयोग करता है और फिर बच्चे ViewModel का समाधान करता है:
public class Factory
{
private readonly IUnityContainer _container;
public Factory(IUnityContainer container)
{
_container = container;
}
public void RegisterStuff()
{
_container.RegisterInstance<Func<IAddress, IAddressViewModel>>(CreateAddressViewModel);
}
private IAddressViewModel CreateAddressViewModel(IAddress model)
{
IUnityContainer childContainer = _container.CreateChildContainer();
childContainer.RegisterInstance(model);
return childContainer.Resolve<IAddressViewModel>();
}
}
अब, जब PersonViewModel
आरंभ नहीं हो जाता है, यह मॉडल और कॉल में प्रत्येक Address
के माध्यम से लूप CreateAddressViewModel()
(जो Func<IAddress, IAddressViewModel>
तर्क के माध्यम से इंजेक्ट किया गया था)। CreateAddressViewModel()
एक अस्थायी बच्चे कंटेनर बनाता है और IAddress
मॉडल पंजीकृत करता है ताकि जब यह बच्चे कंटेनर से IAddressViewModel
निराकरण AddressViewModel
सही उदाहरण, अपना निर्माता के माध्यम से इंजेक्शन हो जाता है।
यह ViewModels की निर्भरता के रूप में मेरे लिए एक अच्छा समाधान हो रहा है बहुत स्पष्ट हैं और वे आसानी से परीक्षण योग्य और आईओसी कंटेनर से अनजान हैं। दूसरी ओर, प्रदर्शन ठीक है लेकिन बहुत अच्छा नहीं है क्योंकि बहुत से अस्थायी बाल कंटेनर बनाए जा सकते हैं। इसके अलावा मैं बहुत ही समान फैक्ट्री विधियों के साथ समाप्त होता हूं।
- क्या यह एकता के साथ बच्चे के मॉडल में बच्चे मॉडल को इंजेक्ट करने का सबसे अच्छा तरीका है?
- क्या अन्य आईओसी कंटेनरों में ऐसा करने के लिए एक बेहतर (या तेज़) तरीका है, उदा। Autofac?
- एमईएफ के साथ इस समस्या का सामना कैसे किया जाएगा, यह देखते हुए कि यह एक पारंपरिक आईओसी कंटेनर नहीं है लेकिन अभी भी वस्तुओं को लिखने के लिए उपयोग किया जाता है?
जैसा कि आप इंगित करते हैं कि निर्दिष्ट पैरामीटर काम नहीं करते हैं अगर किसी भी निर्भरता को मॉडल की आवश्यकता होती है, जो मेरे लिए एक शोस्टॉपर है। बच्चे के कंटेनर का पुन: उपयोग करना एक संभावना है, हालांकि। – GraemeF