2014-09-02 9 views
6

मैं इस प्रश्न को बयान के साथ पेश करने जा रहा हूं: मुझे पता है कि निम्नलिखित खराब डिजाइन है, लेकिन रीफैक्टरिंग वर्तमान में एक विकल्प नहीं है, आदर्श रूप से इसे इंटरसेप्टर का उपयोग करके किया जाना चाहिए।घटक और सेवा निर्भरता के बीच क्या अंतर है?

मैं 1.6 (मुझे लगता है) से 3.3 तक महल को अपग्रेड करने पर काम कर रहा हूं, दुर्भाग्यवश कुछ वाक्यविन्यास परिवर्तन शामिल हैं, मुझे अब सबकुछ संकलित कर रहा है लेकिन सेवा कंटेनर के आसपास मेरे कुछ परीक्षण काम नहीं कर रहे हैं।

कैसल विंडसर पंजीकरण:

मैं भंडार अलग सुविधा प्रदान करने के कई कार्यान्वयन है कि है, भंडार ही कभी अलग कार्यान्वयन इनलाइन के सभी के साथ प्रयोग किया जाता है, यहाँ कोड की मूल बातें हैं

RepositoryRegistration<IAccountRepository, AccountRepositoryFeedEntryDecorator>() 
    .DependsOn(Dependency.OnComponent("decoratedRepository", typeof(AccountRepositoryAuthorizationDecorator))), 
RepositoryRegistration<AccountRepositoryAuthorizationDecorator>() 
    .DependsOn(Dependency.OnComponent("decoratedRepository", typeof(AccountRepositoryMaskingDecorator))), 
RepositoryRegistration<AccountRepositoryMaskingDecorator>() 
    .DependsOn(Dependency.OnComponent("decoratedRepository", typeof(AccountRepository))), 
RepositoryRegistration<AccountRepository>()); 

RepositoryRegistration विधि:

private static ComponentRegistration<TRepository> RepositoryRegistration<TRepository, TConcreteRepository>() 
    where TConcreteRepository : TRepository where TRepository : class 
{ 
    return Component 
       .For<TRepository>() 
       .ImplementedBy<TConcreteRepository>()      
       .Named(typeof(TConcreteRepository).Name); 
} 

आधार इंटरफ़ेस:

public interface IAccountRepository 
{ 
    string Create(Account account); 
    void Update(Account account); 
    Account Get(string accountId); 
} 

कार्यान्वयन:

Castle.MicroKernel.Handlers.HandlerException: घटक नहीं बना सकता '

public class AccountRepositoryFeedEntryDecorator : IAccountRepository 
{ 
    private readonly IAccountRepository decoratedRepository; 
    public AccountRepositoryFeedEntryDecorator(
     IAccountRepository decoratedRepository) 
    { 
     this.decoratedRepository = decoratedRepository; 
    } 

    string Create(Account account) 
    { 
     //Add Entry To Feed 
     return decoratedRepository.Create(account); 
    }; 

    void Update(Account account) 
    { 
     //Add Entry To Feed 
     return decoratedRepository.Udpate(account); 
    } 
    Account Get(string accountId); 
    { 
     //Add Entry To Feed 
     return decoratedRepository.Get(accountId); 
    } 
} 

public class AccountRepositoryAuthorizationDecorator : IAccountRepository 
{ 
    private readonly IAccountRepository decoratedRepository; 
    public AccountRepositoryAuthorizationDecorator(
     IAccountRepository decoratedRepository) 
    { 
     this.decoratedRepository = decoratedRepository; 
    } 

    string Create(Account account) 
    { 
     //Ensure User Is Authorized 
     return decoratedRepository.Create(account); 
    }; 

    void Update(Account account) 
    { 
     //Ensure User Is Authorized 
     return decoratedRepository.Udpate(account); 
    } 
    Account Get(string accountId); 
    { 
     //Ensure User Is Authorized 
     return decoratedRepository.Get(accountId); 
    } 
} 

public class AccountRepositoryMaskingDecorator : IAccountRepository 
{ 
    private readonly IAccountRepository decoratedRepository; 
    public AccountRepositoryMaskingDecorator(
     IAccountRepository decoratedRepository) 
    { 
     this.decoratedRepository = decoratedRepository; 
    } 

    string Create(Account account) 
    { 
     //Mask Sensitive Information 
     return decoratedRepository.Create(account); 
    }; 

    void Update(Account account) 
    { 
     //Mask Sensitive Information 
     return decoratedRepository.Udpate(account); 
    } 
    Account Get(string accountId); 
    { 
     //Mask Sensitive Information 
     return decoratedRepository.Get(accountId); 
    } 
} 

public class AccountRepository : IAccountRepository 
{  
    string Create(Account account) 
    { 
     //Create account and return details 
    }; 

    void Update(Account account) 
    { 
     //Update account and return details 
    } 
    Account Get(string accountId); 
    { 
     //Return Account 
    } 
} 

और अंत में यहाँ त्रुटि मैं अपने परीक्षण में हो रही है AccountRepositoryFeedEntryDecorator 'क्योंकि इसकी संतुष्टि संतुष्ट होने के लिए है। (ओवरराइड के माध्यम से) जो पंजीकृत किया गया था, लेकिन यह भी निर्भरता के लिए इंतज़ार कर रहा है घटक 'Shaw.Services.CustomerManagement.Host.Repositories.Sql.Decorators.AccountRepositoryAuthorizationDecorator' - :

'AccountRepositoryFeedEntryDecorator' निम्न निर्भरता के लिए इंतज़ार कर रहा है।

'Shaw.Services.CustomerManagement.Host.Repositories.Sql.Decorators.AccountRepositoryAuthorizationDecorator' निम्न निर्भरता के लिए इंतज़ार कर रहा है: - सेवा 'AccountRepositoryFeedEntryDecorator' जो पंजीकृत किया गया था, लेकिन यह भी निर्भरता के लिए इंतज़ार कर रहा है।

पहली नज़र में ऐसा लगता है कि कुछ प्रकार की परिपत्र निर्भरता हो रही है, लेकिन मैं वास्तव में कैसे देख सकता हूं।

तो दो भागों में सवाल, त्रुटि संदेश में घटक और सेवा निर्भरता विनिर्देशों के बीच क्या अंतर है, किसी भी अनुमान के बारे में कोई अनुमान है कि क्या गलत हो रहा है।

तो इसे यहाँ मायने रखती अपग्रेड से पहले वह मूल पंजीकरण है:

RepositoryRegistration<IAccountRepository, AccountRepositoryFeedEntryDecorator>() 
    .ServiceOverrides(new { decoratedRepository = typeof(AccountRepositoryAuthorizationDecorator).Name }), 
RepositoryRegistration<AccountRepositoryAuthorizationDecorator>() 
    .ServiceOverrides(new { decoratedRepository = typeof(AccountRepositoryMaskingDecorator).Name }), 
RepositoryRegistration<AccountRepositoryMaskingDecorator>() 
    .ServiceOverrides(new { decoratedRepository = typeof(AccountRepository).Name }), 
RepositoryRegistration<AccountRepository>() 

उत्तर

6

डेकोरेटर पंजीकरण पंजीकरण क्रम में होता है और आप निर्भरता निर्दिष्ट करने की आवश्यकता नहीं है, इसलिए इस तरह आप उम्मीद थी काम करेंगे:

container.Register(
    RepositoryRegistration<IAccountRepository, AccountRepositoryFeedEntryDecorator>(), 
    RepositoryRegistration<IAccountRepository, AccountRepositoryAuthorizationDecorator>(), 
    RepositoryRegistration<IAccountRepository, AccountRepositoryMaskingDecorator>(), 
    RepositoryRegistration<IAccountRepository, AccountRepository>() 
); 

IAccountRepository का एक उदाहरण का समाधान करना एक AccountRepositoryFeedEntryDecorator है, जो एक AccountRepositoryAuthorizationDecorator से सजाया गया निकलेगा, आदि


अपने प्रश्न के रूप में, this page एक महान काम सेवाओं, घटकों, और निर्भरता के बीच मतभेदों को समझाने के रूप में संदर्भ पुस्तकालय के भीतर उपयोग किया जाता है है। मूलतः:

  • सेवा कार्यक्षमता के कुछ अनुबंध, आम तौर पर एक इंटरफेस या प्रतिनिधि है। यह सार है।
  • घटक एक सेवा का कार्यान्वयन है, आमतौर पर एक वर्ग। यह ठोस है।
  • निर्भरता एक सेवा है जो एक घटक का उपयोग करता है।

अपने त्रुटि संदेश में, पहली बिट है:

Castle.MicroKernel.Handlers.HandlerException: घटक 'AccountRepositoryFeedEntryDecorator' नहीं बना सकता क्योंकि यह निर्भरता है संतुष्ट होना।

ठीक है, इसलिए क्योंकि इसके निर्भरता संतुष्ट नहीं हो सकता है घटक/वर्ग नहीं बनाया जा सकता। यह निर्भरता कन्स्ट्रक्टर में IAccountRepository decoratedRepository पैरामीटर है। (ओवरराइड के माध्यम से) जो पंजीकृत किया गया था, लेकिन यह भी निर्भरता के लिए इंतज़ार कर रहा है घटक 'AccountRepositoryAuthorizationDecorator' -:

'AccountRepositoryFeedEntryDecorator' निम्न निर्भरता के लिए इंतज़ार कर रहा है।

हम अभी भी एक ही घटक/वर्ग के बारे में बात कर रहे हैं, और यह कह रहा है कि वह अपने निर्भरता को पूरा करने के घटक/वर्ग AccountRepositoryAuthorizationDecorator उपयोग करने के लिए कोशिश कर रहा था, लेकिन वह वर्ग भी निर्भरता है।

'AccountRepositoryAuthorizationDecorator' निम्न निर्भरता के लिए इंतज़ार कर रहा है: - सेवा 'AccountRepositoryFeedEntryDecorator' जो पंजीकृत किया गया था, लेकिन यह भी निर्भरता के लिए इंतज़ार कर रहा है।

और हम पहले वर्ग में आ गए हैं, इसलिए एक परिपत्र निर्भरता है। यह RepositoryRegistration में सेट नाम के बीच एक डिस्कनेक्ट की वजह से है और जब आप किसी प्रकार में Dependency.OnComponent पर जाते हैं तो गणना की गई गणना। पूर्व के लिए, आप Type.Name (यानी, "AccountRepositoryFeedEntryDecorator") का उपयोग कर रहे हैं, और बाद के विंडसर के लिए कवर के तहत Type.FullName का उपयोग करता है (यानी, "Your.Assembly.Name, AccountRepositoryFeedEntryDecorator")।

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

आप पंजीकरण के Named भाग को हटाकर या typeof(AccountRepositoryAuthorizationDecorator).NameDependency.OnComponent को अपने आप के बजाय पास करके इसे हल कर सकते हैं।

+0

हाय पैट्रिक, मैंने अभी इस समाधान की कोशिश की लेकिन अब मुझे एक त्रुटि मिलती है जो पहली बार शिकायत करती है कि यह सेवा पर वापस इशारा कर रहा है, फिर कहता है कि अन्य घटक भी हैं जो समान 'परिपत्र' निर्भरता मुद्दे के साथ मेल खाते हैं। – Phaeze

+0

मैं इसे दूसरी नज़र में वापस लेता हूं, यह पूरी तरह से एक अलग पंजीकरण मुद्दे की तरह दिखता है। – Phaeze

+0

@ फीज आह ठीक है, ठीक है अगर यह संबंधित है तो अपने प्रश्न को अपडेट करने के लिए स्वतंत्र महसूस करें, अन्यथा यह एक नए प्रश्न के रूप में पूरी तरह से समझ में आ सकता है। –

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