2011-11-04 17 views
6

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

ObjectFactory.Initialize(x => 
{ 
    x.AddRegistry<RegistryIOC>(); 
}); 

और यहाँ मेरी RegistryIOC वर्ग है:

public class RegistryIOC : SMRegistry 
{ 

    public RegistryIOC() 
    { 
     For<IProfileService>.Use<ProfileService>(); 
     For<IProctorService>().Use<ProctorService>(); 

     //Business Logic Objects 
     For<IQual>().Use<Qual>(); 
     For<ITest>().Use<Test>(); 
     For<IBoldface>().Use<Boldface>(); 
     For<ITrainingPlan>().Use<TrainingPlan>(); 
     For<IUnit>().Use<Unit>(); 

     //Data Transfer Objects 
     For<IGenericDTO>().Use<GenericDTO>(); 
     For<IProfileDTO>().Use<ProfileDTO>(); 
     For<IQualDTO>().Use<QualDTO>(); 
     For<IPermissionDTO>().Use<PermissionDTO>(); 

     //Repository Objects 
     For<IProctorRepository>().Use<ProctorRepository>(); 
     For<IQualsRepository>().Use<QualsRepository>(); 
     For<ITestRepository>().Use<TestRepository>(); 
     For<IUnitRepository>().Use<UnitRepository>(); 
     For<IUserRepository>().Use<UserRepository>(); 
    } 

} 

मदद के लिए धन्यवाद

यहाँ मेरी Global.asax फ़ाइल में कोड है।

+0

आप किस तरह की परतों के बारे में बात कर रहे हैं? विभिन्न प्रक्रियाओं? विभिन्न मशीनें?यदि वे सभी एक ही प्रक्रिया में चल रहे हैं, तो संभवतया, इसके इंटरफ़ेस के बारे में, आप शायद अपनी व्यावसायिक परत * आपके डेटा परत के बारे में * थोड़ा * जानते हैं। यह अस्पष्ट है कि आप किस समस्या को हल करने की कोशिश कर रहे हैं। आपकी रजिस्ट्रीआईओसी कक्षा में क्या गलत है? –

+0

हमारे पास एक सेवा परत, बीएलएल, और डीएएल है जो सभी अलग परियोजनाएं हैं। प्रत्येक परियोजना संदर्भ संरचना मैप। सेवा परत अन्य दो परतों के बारे में जानता है लेकिन बीएलएल और डीएएल एक-दूसरे के बारे में नहीं जानते हैं। मैं नहीं चाहता कि अन्य डेवलपर्स डीएएल के भीतर से बिजनेस ऑब्जेक्ट्स का उपयोग कर रहे हों और इसके विपरीत मैं नहीं चाहता कि डेवलपर्स बीएलएल के भीतर से रिपोजिटरी ऑब्जेक्ट्स का उपयोग कर सकें। सर्विस लेयर उस सब को व्यवस्थित करता है। तो सभी प्रकार के पंजीकरण का उपयोग करके इस तरह की सभी वस्तुओं को हमारी सभी परतों (परियोजनाओं) में उपलब्ध कराया जाता है। –

+0

ठीक है, * संरचना रूट की तुलना में किसी अन्य परत से स्ट्रक्चर मैप का संदर्भ जोड़ें ... –

उत्तर

3

मैं इस (और अन्य) कार्यों को पूरा करने के लिए प्रतिबिंब का उपयोग कर रहा हूं। मुझे दिखाएं कि यह कैसे काम करता है। ,

public interface IConfigurationTask 
{ 
    void Configure(); 
} 

अगला एक या अधिक वर्गों है कि इस इंटरफ़ेस को लागू बनाने के लिए:

करने के लिए पहली बात यह है एक अंतरफलक है कि हम कक्षाओं कि प्रारंभ कार्यों को पहचान करने के लिए अनुमति देता है परिभाषित करने के लिए है। ये कक्षाएं आपकी सभी परियोजनाओं में फैली होंगी, जो कहने का एक और तरीका है कि आप उन्हें "जहां वे संबंधित हैं" डाल सकते हैं।

public class RepositoryInitializer : IConfigurationTask 
{ 
    public void Configure() 
    { 
     // code that does relevant initialization goes here 
    } 
} 

पहेली के अंतिम टुकड़ा कक्षाएं कि IConfigurationTask इंटरफ़ेस को लागू लगता है, उनमें से एक उदाहरण बना सकते हैं और कॉन्फ़िगर विधि निष्पादित करने के लिए है।

public static class ConfigurationTaskRunner 
{ 
    public static void Execute(params string[] assemblyNames) 
    { 
     var assemblies = assemblyNames.Select(Assembly.Load).Distinct().ToList(); 
     Execute(assemblies); 
    } 

    public static void Execute(IEnumerable<Assembly> assemblies) 
    { 
     var tasks = new List<IConfigurationTask>(); 
     assemblies.ForEach(a => tasks.AddRange(a.CreateInstances<IConfigurationTask>())); 

     tasks.ForEach(t => t.Configure()); 
    } 
} 

कोड यहाँ दिखाया गया है एक सूची में सभी आइटम से अधिक पुनरावृति और हर आइटम (foreach विधि) के लिए एक कार्य निष्पादित करने के लिए एक कस्टम एक्सटेंशन का उपयोग करता है: यह ConfigurationTaskRunner का उद्देश्य है। मैं उदाहरणों को ढूंढने और तुरंत एक-लाइनर (CreateInstances विधि) को तुरंत चालू करने के लिए reflection library का उपयोग कर रहा हूं, लेकिन आप केवल सादे प्रतिबिंब (जैसा कि नीचे दिए गए कोड में दिखाया गया है) का उपयोग करके इसे प्राप्त कर सकते हैं।

public static IList<T> CreateInstances<T>(this Assembly assembly) 
{ 
    var query = from type in assembly.GetTypes().Where(t => typeof(T).IsAssignableFrom(t) && typeof(T) != t) 
       where type.IsClass && ! type.IsAbstract && type.GetConstructor(Type.EmptyTypes) != null 
       select (T) Activator.CreateInstance(type); 
    return query.ToList(); 
}  

पहेली का अंतिम भाग कॉन्फ़िगरेशन टास्करनर के निष्पादन को ट्रिगर करना है। उदाहरण के लिए, एक वेब अनुप्रयोग में इस Global.asax में Application_Start में जाना होगा:

// pass in the names of the assemblies we want to scan, hardcoded here as an example 
ConfigurationTaskRunner.Execute("Foo.dll", "Foo.Domain.dll"); 

मैं भी यह एक व्युत्पन्न IPrioritizedConfigurationTask (है कि एक प्राथमिकता संपत्ति कहते हैं) के साथ उपयोगी से पहले कार्य का सही क्रम अनुमति देने के लिए मिल गया है आप उन्हें निष्पादित करते हैं। यह उपरोक्त उदाहरण कोड में नहीं दिखाया गया है, लेकिन जोड़ने के लिए काफी छोटा है।

आशा है कि इससे मदद मिलती है!

+0

इस उदाहरण में (जो कमाल है) आप निर्भरताओं को चेन करने का प्रस्ताव कैसे देते हैं? अगर मैं आईप्रोड्रिपो का एक उदाहरण चाहता था जिसे प्रोड कैशरेपो द्वारा समर्थित किया गया था जिसे प्रोड्रिपो द्वारा समर्थित किया गया था ... आप उस श्रृंखला को कैसे करेंगे? जिज्ञासु! –

+0

@AndrewSiemer मुझे लगता है कि आईओसी फ्रेमवर्क (इस मामले में स्ट्रक्चर मैप) का कार्य होगा, जो आप इसे प्रदान करने वाले कॉन्फ़िगरेशन के आधार पर (व्यक्तिगत कॉन्फ़िगरेशन विधियों में)। मेरे द्वारा प्रदान किया गया कोड आईओसी कंटेनर (या जो भी आपको एप्लिकेशन स्टार्टअप पर प्रारंभ करने की आवश्यकता है) के "वितरित विन्यास" के लिए एक तंत्र है। –

+0

मैं प्रतिबिंब पुस्तकालय का उपयोग नहीं कर सकता। जब मैं नियमित रूप से प्रतिबिंब के माध्यम से इस कोड को आज़माता हूं, ए। क्रिएट इंस्टेंस ("आईसीओफ़िगरेशन टास्क"), मुझे परिणाम के रूप में कुछ भी नहीं मिलता है। हो सकता है कि मुझे कहीं कुछ याद आ रहा है ... :-( –

0

आप कई स्वतंत्र Container उदाहरण बना और कॉन्फ़िगर कर सकते हैं और सभी see this article पर स्थिर ObjectFactory का उपयोग न करें। उचित परतों में उचित कंटेनर प्रदान करना आपकी ज़िम्मेदारी होगी।

वैसे, आप इंटर-लेयर संचार को कैसे संभालना चाहते हैं? क्या यह किसी भी तरह मुश्किल नहीं होगा? मैं रजिस्ट्रियों को विभाजित करना चाहता हूं (संभावित रूप से असेंबली अलग करने के लिए) और बुनियादी ढांचे स्तर पर decoupling लागू करने के बजाय इसे "मैन्युअल" decoupled रखें।

+0

मुझे अपने वर्तमान कार्यान्वयन को बिल्कुल बदलना नहीं है। यदि मेरे पास मेरी प्रत्येक परत पर कक्षाओं से अलग सभी रजिस्ट्रीज़ हैं जो मेरे साथ शांत हैं। मेरी समस्या का एक हिस्सा यह है कि मैं पूरी तरह समझ नहीं पा रहा हूं कि "उचित परतों के लिए उचित कंटेनर कैसे प्रदान करें।" मैं ग्लोबल.एक्सएक्स लोडर में वास्तव में क्या डालूं? –

+0

ठीक है, आम तौर पर आपको अलग-अलग परतों के लिए अलग-अलग प्रविष्टि बिंदु रखना होगा और प्रत्येक परत को उचित कंटेनर का उपयोग करके अपनी फैक्ट्री विधि (ओं) की आवश्यकता होगी - इस तरह आपके पास प्रत्येक परत के लिए अलग ऑब्जेक्ट ग्राफ़ होंगे। लेकिन मैं वास्तव में नहीं देखता कि इस तरह के ग्राफ के बीच किसी भी बातचीत को कैसे पूरा किया जाए, इसलिए यही कारण है कि दूसरे पैराग्राफ में प्रश्न हैं। अंत में आपके पास कुछ प्रकार के ऊपरी-परत घटक एक्स होते हैं जो निम्न-स्तर के घटक वाई का उपयोग करते हैं। यदि एक्स मध्यम-परत है और मध्यम-परत कंटेनर द्वारा बनाया गया है, तो इसकी निर्भरता वाई है, भले ही यह नीचे-परत से हो । – NOtherDev

+0

तो आम तौर पर जवाब यह है कि ऑब्जेक्ट ग्राफ को पूरी तरह से डीकॉप्ल करना मुश्किल है। यही कारण है कि मैंने वस्तु कारखाने के स्तर की बजाय रजिस्ट्री/असेंबली स्तर पर decoupling का सुझाव दिया। – NOtherDev

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