2010-10-31 9 views
6
public interface IRepository<T> where T : Entity 
{ 
    void Delete(T entity); 
    T[] GetAll(); 
    T GetById(int id); 
    void SaveOrUpdate(T enity); 
    void Merge(T entity); 
} 

public interface ITeamEmployeeRepository : IRepository<TeamEmployee> 
{ 
    PagedList<TeamEmployee> GetPagedTeamEmployees(int pageIndex, int pageSize); 
} 


public class Repository<T> : IRepository<T> where T : Entity 
{ 
    private readonly ISession _session; 

    protected Repository() 
    { 
     _session = GetSession(); 
    } 

    public virtual void Delete(T entity) 
    { 
     _session.Delete(entity); 
    } 

    public virtual T[] GetAll() 
    { 
     return _session.CreateCriteria<T>().List<T>().ToArray(); 
    } 

    public virtual T GetById(int id) 
    { 
     return _session.Get<T>(id); 
    } 

    public virtual void SaveOrUpdate(T enity) 
    { 
     _session.SaveOrUpdate(enity); 
    } 

    public void Merge(T entity) 
    { 
     _session.Merge(entity); 
    } 

    protected ISession GetSession() 
    { 
     return new SessionBuilder().GetSession(); 
    } 
} 

public class TeamEmployeeRepository : Repository<TeamEmployee>, ITeamEmployeeRepository 
{ 
    public PagedList<TeamEmployee> GetPagedTeamEmployees(int pageIndex, int pageSize) 
    { 
     return GetSession().QueryOver<TeamEmployee>() 
      .Fetch(x => x.Employee).Eager 
      .Fetch(x => x.Team).Eager 
      .ToPagedList(pageIndex, pageSize); 
    } 
} 

के लिए अब मैं भंडार रजिस्टर इस प्रकार है:StructureMap - रजिस्टर करने के लिए कैसे और हल एक खुला सामान्य प्रकार

For<ILoanedItemRepository>().Use<LoanedItemRepository>(); 
For<ITeamEmployeeRepository>().Use<TeamEmployeeRepository>(); 
For<IArticleRepository>().Use<ArticleRepository>(); 
For<ISalesmanRepository>().Use<SalesmanRepository>(); 
For<ISalesmanArticleRepository>().Use<SalesmanArticleRepository>(); 
For<IGoodsGroupRepository>().Use<GoodsGroupRepository>(); 
For<IEmployeeRepository>().Use<EmployeeRepository>(); 

यह विशेष रूप से अगर कोई नया खजाने साथ आता है वास्तव में बोझिल है,।

एक आसान और बेहतर पंजीकरण होगा:

For(typeof(IRepository<>)).Use(typeof(Repository<>)); 

लेकिन यह काम नहीं करता। स्ट्रक्चर मैप हर बार मुझे कह रहा है कि प्लगइनफैमिली कोर के लिए कोई डिफ़ॉल्ट इंस्टेंस परिभाषित नहीं किया गया है। डॉमेन.बेस. रिपॉजिटरीज.आईटीएमएम नियोक्ता रिपोजिटरी।

मैं stackoverflow पर खोज की है और कुछ नया पाया:

Scan(x => 
{ 
    x.AssemblyContainingType(typeof(TeamEmployeeRepository)); 
    x.AddAllTypesOf(typeof (IRepository<>)); 
    x.ConnectImplementationsToTypesClosing(typeof(IRepository<>)); 
}); 

लेकिन अब भी वही त्रुटि।

मुझे अपनी रिपॉजिटरीज को स्ट्रक्चर मैप 2.6.1.0 के साथ कैसे पंजीकृत करना है?

+0

हालांकि यह सीधे आपके प्रश्न का उत्तर नहीं देता है, कृपया इस आलेख पर एक नज़र डालें: http://stackoverflow.com/questions/4128640/how-to-remove-unit-of-work- कार्यक्षमता-from-repositories-using -ioc/41 32,186 # 4,132,186। यह भंडार पैटर्न को लागू करने का एक वैकल्पिक तरीका दिखाता है। कार्यान्वयन आपके भंडारों को काम की एक इकाई के पीछे छुपाता है और आपको केवल एक 'IUnitOfWorkFactory' पंजीकृत करने की आवश्यकता होती है और आप कर चुके हैं। – Steven

उत्तर

7

मुझे एक समाधान मिला है। क्योंकि इस सेटिंग के साथ आप कहते हैं StructureMap TeamEmployeeRepository को ITeamEmployeeRepository mappping के सम्मेलन का उपयोग करने के

Scan(x => 
{ 
    x.WithDefaultConventions(); 
    x.AssemblyContainingType(typeof(TeamEmployeeRepository)); 
    x.AddAllTypesOf(typeof(Repository<>)); 
    x.ConnectImplementationsToTypesClosing(typeof(IRepository<>)); 
}); 

WithDefaultConventions, दिखाए गए कोड का महत्वपूर्ण हिस्सा है। तो स्ट्रक्चर मैप इस धारणा से आगे बढ़ता है कि वर्ग को I के बिना इंटरफेस के नाम की तरह नामित किया गया है।

-1

मैंने हाल ही में एक छोटा रीडिज़ाइन करके कुछ हल किया, जिसने सबकुछ इतना आसान बना दिया। यह आपके लिए भी काम कर सकता है। आप अपने डिजाइन से ITeamEmployeeRepository और ILoanedItemRepository जैसे विशिष्ट इंटरफेस को हटाने का प्रयास कर सकते हैं। जिस तरह से मैंने विस्तार विधियों का उपयोग करके किया था।

public static class RepositoryExtensions 
{ 
    public static TeamEmployee GetById(
     this IRepository<TeamEmployee> repository, int id) 
    { 
     return repository.Single(e => e.TeamEmployeeId == id); 
    } 

    public static IQueryable<Salesman> GetActiveSalesmen(
     this IRepository<ISalesmanRepository> repository) 
    { 
     return repository.Where(salesman => salesman.Active); 
    } 

    // etc 
} 

है कि मैं एक IRepositoryFactory है कि मुझे एक खास प्रकार के खजाने बनाने के लिए अनुमति बनाया करने के बाद: यहाँ एक उदाहरण है

public interface IRepositoryFactory 
{ 
    IRepository<T> CreateNewRepository<T>(); 
} 

जब जगह में इस इंटरफेस होने के एक कार्यान्वयन बनाने के लिए आसान है यह कारखाना कंटेनर को कंक्रीट Repository<T> बनाने के लिए कहता है। RepositoryFactory ऐसा दिखाई दे सकता:

public class RepositoryFactory : IRepositoryFactory 
{ 
    public IRepository<T> CreateNewRepository<T>() 
    { 
     return ObjectFactory.GetInstance(typeof(Repository<T>)); 
    } 
} 
इस डिजाइन आप केवल अपने IRepositoryFactory इंटरफ़ेस द्वारा ठोस RepositoryFactory रजिस्टर करने के लिए है के साथ

और आपका काम हो गया। पुराने डिजाइन में IRepository<ITeamEmployeeRepository> इंजेक्शन करने के बजाय, अब आप IRepositoryFactory इंजेक्ट करें और क्लाइंट को CreateNewRepository<T> विधि कॉल करें। विस्तार विधियों के उपयोग के कारण आप भंडार पर विशिष्ट विधियों को टाइप कर सकते हैं।

इसका एक अन्य लाभ यह है कि आपको उन तरीकों को फिर से कार्यान्वित करने की आवश्यकता नहीं है जिन्हें आपने प्रारंभ में ITeamEmployeeRepository पर प्रत्येक कार्यान्वयन पर परिभाषित किया था।

यह डिज़ाइन मेरी स्थिति में बहुत अच्छा काम करता है, खासकर क्योंकि मेरे IRepository<T> इंटरफेस अभिव्यक्ति पेड़ों का उपयोग करते हैं। बेशक यह देखना मेरे लिए संभव नहीं है कि यह डिज़ाइन आपके लिए काम करता है लेकिन मुझे उम्मीद है कि यह होगा।

शुभकामनाएं।

+0

"इसका एक अन्य लाभ यह है कि आपको उन तरीकों को फिर से कार्यान्वित करने की आवश्यकता नहीं है जिन्हें आपने आरंभ में प्रत्येक कार्यान्वयन पर ITEamEmployeeRepository पर परिभाषित किया था।" यह मामला नहीं है, क्योंकि रिपोजिटरी पहले से ही मानक सीआरयूडी सामग्री को कार्यान्वित कर रहा है। विशिष्ट ITeamEmployeeRepository में केवल विशिष्ट आवश्यकताएं हैं। – Rookian

+0

शायद मैं गलत समझता हूं, लेकिन मैंने कल्पना की कि आप टीम कर्मचारी विशिष्ट तरीकों के लिए 'ITEamEmployeeRepository' का उपयोग करेंगे। इन विधियों का 'रेपोजिटरी ' कक्षा में कोई अर्थ नहीं होगा। मुझे लगता है कि आपके पास उस इंटरफ़ेस पर इकाई विशिष्ट विधियां हैं, क्योंकि विधियों के बिना इंटरफ़ेस बहुत उपयोगी नहीं होगा। 'GetByYear' या CRUD संचालन जैसी चीजें जिनके पास रिपोजिटरी पर कोई अर्थ नहीं है। आपके पास आमतौर पर इस 'ITEamEmployeeRepository' इंटरफ़ेस का कम से कम दो कार्यान्वयन होगा ... – Steven

+0

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

-2

आपको अपना खुद का ITypeScanner बनाना होगा और इसे अपने Scan() कॉल में पंजीकृत करना होगा। शुरुआती बिंदु के रूप में GenericConnectionScanner के स्रोत कोड को देखें। यह देखने के लिए कि क्या वे IRepository<T> लागू करते हैं, यह देखने के लिए कि आप IRepository<T> लागू करते हैं, और उसके बाद उस इंटरफ़ेस के प्रकार को पंजीकृत करते हैं, तो आप यह देखने के लिए देखेंगे कि क्या वे IRepository<T> लागू करते हैं।

अद्यतन: IRepository<T> की सभी बातों ने मुझे यह सोचने पर विचार किया, जब यह वास्तव में एक अप्रासंगिक विवरण है। रूकियन द्वारा सुझाए गए डिफ़ॉल्ट कन्वेंशन स्कैनर का उपयोग करें।

2

मुझे यह प्रश्न गुगलिंग "स्ट्रक्चरमैप जेनेरिक जेनेरिक" मिला। मौजूदा उत्तर अच्छे लेकिन जटिल हैं। इसका सरल उत्तर पाने के इच्छुक लोगों के लिए: और लागू करने वर्ग इंटरफ़ेस ISome के लिए कुछ हम

c.For<ISome>().Use<Some>() 

लिखने जबकि सामान्य ISome < टी > और लागू करने वर्ग कुछ < टी > के लिए हम

c.For(typeof(ISome<>)).Use(typeof(Some<>)) 

बारे में और वह सब

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

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