2011-06-24 6 views
13

मैं रेजर दृश्यों का उपयोग करके एएसपी.नेट एमवीसी 3 के लिए एक प्लगइन ढांचा तैयार कर रहा हूं, और मुझे एम्बेडेड दृश्य सही तरीके से काम करने में कोई समस्या है।एएसपी.नेट एमवीसी 3 और एम्बेडेड रेज़र विचारों के साथ एक प्लगइन ढांचा

प्लगइन ढांचे इन सुविधाओं के लिए बनाया गया है:

  • प्रत्येक प्लगइन का अपना मॉडल, नियंत्रकों और नजारा दिखता है। विचारों एम्बेड किए गए संसाधन, और नियंत्रकों एक PluginController वर्ग से निकाले जाते हैं
  • प्लगइन्स एक साझा वर्ग पुस्तकालय है कि PluginController आधार वर्ग
  • "खोल" वेब एप्लिकेशन है जो प्लगइन्स होस्ट करता है परिभाषित करता है करने के लिए निर्भरता संदर्भ हो रहे हैं को डिजाइन समय पर किसी भी प्लगइन के संदर्भ नहीं रखना चाहिए, क्योंकि यह डिज़ाइन समय पर नहीं है जो प्लगइन है।
    1. प्लगइन्स की खोज (प्रतिबिंब का उपयोग)
    2. पंजीयन:
    3. प्लगइन dll के खोल आवेदन पत्र में एक फ़ोल्डर, जो /bin फ़ोल्डर
    4. खोल का ख्याल रखता है नहीं है में शामिल नहीं किया जाता सभी नियंत्रक (मैं इस के लिए Spring.Net उपयोग कर रहा हूँ)
    5. नियंत्रकों
    6. VirtualPathProvider एक कस्टम के माध्यम से उस्तरा फ़ाइलें (cshtml) की सेवा करने के लिए बनाया जा रहा है मार्गों

अब सबकुछ ठीक काम करता है, सिवाय इसके कि एम्बेडेड दृश्यों में प्लगइन डीएल के प्रकारों के संदर्भ होते हैं। तब मैं कुख्यात त्रुटि मिलती है (नाम बाहर छोड़ दिया):

The type or namespace name '[Plugins]' does not exist in the namespace '[MyPluginSolution]' (are you missing an assembly reference?)

इस का कारण यह है कि सीएससी संकलक जो क्रम शुरू हो जाती है उस्तरा विचारों को संकलित करने के है केवल मिल बिन फ़ोल्डर से dll संदर्भ और जीएसी

मैंने this technique का उपयोग करके विचारों को पूर्व-संकलित करने का भी प्रयास किया है, लेकिन अंत में यह वही परिणाम देता है, क्योंकि रनटाइम पूर्व-संकलित रेज़र दृश्य के लिए एक रैपर को संकलित करने पर जोर देता है।

मैं निश्चित रूप से/bin फ़ोल्डर में प्लगइन dll छोड़ सकता है, लेकिन मेरे सवाल यह है:

वहाँ (और गैर GAC) एक गैर बिन में DLLs रजिस्टर करने के लिए एक रास्ता है फ़ोल्डर, और इलाज उन्हें "प्रथम श्रेणी के नागरिक" के रूप में, ताकि वे रेजर विचारों द्वारा उपयोग किए जा सकें?

उत्तर

14

ठीक है, समाधान this article का उपयोग कर पाया गया था।

सबसे पहले मैं PreApplicationStartMethod के साथ एक कक्षा बना देता हूं। यह विधि प्लगइन फ़ोल्डर स्कैन करती है और डीएलएस को AppDomain.DynamicDirectory पर कॉपी करती है।

तब इनमें से प्रत्येक डीएल BuildManager.AddReferencedAssembly का उपयोग करके लोड किया जाता है।

और voilà, दृढ़ता से टाइप किए गए रेजर दृश्य खूबसूरती से संकलित करते हैं।

[assembly: PreApplicationStartMethod(typeof(MySolution.PluginHandler.PluginActivator), "Initialize")] 
namespace MySolution.PluginHandler 
{ 
    public class PluginActivator 
    { 
     private static readonly DirectoryInfo PluginFolderInfo; 

     static PluginActivator() { 
      PluginFolderInfo = new DirectoryInfo(HostingEnvironment.MapPath("~/plugins")); 
     } 

     public static void Initialize() { 
      CopyPluginDlls(PluginFolderInfo, AppDomain.CurrentDomain.DynamicDirectory); 
      LoadPluginAssemblies(AppDomain.CurrentDomain.DynamicDirectory); 
     } 

     private static void CopyPluginDlls(DirectoryInfo sourceFolder, string destinationFolder) 
     { 
      foreach (var plug in sourceFolder.GetFiles("*.dll", SearchOption.AllDirectories)) { 
       if (!File.Exists(Path.Combine(destinationFolder, plug.Name))) { 
        File.Copy(plug.FullName, Path.Combine(destinationFolder, plug.Name), false); 
       } 
      } 
     } 

     private static void LoadPluginAssemblies(string dynamicDirectory) 
     { 
      foreach (var plug in Directory.GetFiles(dynamicDirectory, "*.dll", SearchOption.AllDirectories)) { 
       Assembly assembly = Assembly.Load(AssemblyName.GetAssemblyName(plug)); 
       BuildManager.AddReferencedAssembly(assembly); 
      } 
     } 
    } 
} 

मुझे आशा है कि यह अन्य प्रोग्रामर कि इन नई तकनीकों का उपयोग करते हुए एक स्वच्छ प्लगइन ढांचे का निर्माण करना चाहते मदद कर सकते हैं: यहाँ कोड देखें।

+0

बिन डीआईआर में प्लगइन डालने का कारण यह नहीं है कि आप ऐप को पुनरारंभ नहीं करना चाहते हैं? यह समाधान केवल ऐप स्टार्ट-अप (BuildManager.AddReferencedAssembly) पर एक प्लगइन लोड करता है - क्या गतिशील डायरेक्टरी में गतिशील रूप से असेंबली को संदर्भित करना संभव है? –

+0

कारण यह है कि इस समाधान में संभावित रूप से बड़ी संख्या में प्लगइन हो सकते हैं, प्रत्येक में 3-5 डीएलएस होते हैं। और चूंकि आप उन्हें उप-फ़ोल्डरों में/बिन के नीचे नहीं डाल सकते हैं, इसलिए पसंदीदा समाधान इस के लिए एक और फ़ोल्डर का उपयोग करना था। – lasseschou

1

डेविड एब्बो ने हाल ही में असेंबली में रेज़र विचारों को प्रीकंपलिंग करने के बारे में ब्लॉग किया। आप here पोस्ट देख सकते हैं।

आप असेंबली को गतिशील रूप से लोड करके सीधे असेंबली को पंजीकृत करने से बचने में सक्षम होना चाहिए (मैं आमतौर पर इसके लिए अपने आईओसी कंटेनर का उपयोग करता हूं) और फिर BuildManager को कॉल करता हूं। प्रत्येक प्लगइन असेंबली के लिए AddReferencedAssembly।

+0

धन्यवाद बेन। लेकिन अपने मामले में, क्रिस वैन डी स्टिग के मामले की तरह, होस्ट एप्लायंस के प्लगइन असेंबली का सीधा संदर्भ है, इसलिए यह दुर्भाग्य से मेरी समस्या का समाधान नहीं करता है। – lasseschou

+0

मैंने अपना जवाब अपडेट कर लिया है लेकिन ध्यान दें कि यह सब "सिद्धांत में है" :) - अधिक जानकारी http://haacked.com/archive/2010/05/16/three-hidden-extensibility-gems-in-asp-net -4.aspx –

+0

हाय बेन, आपके नवीनतम संपादन ने मुझे सही दिशा में इंगित किया। समाधान एक प्री-एप्लिकेशन_स्टार्ट विधि शामिल करना था जो सभी प्लगइन डीएल को ऐपडॉमेन। डायनेमिक डायरेक्टरी में कॉपी करता है, और बाद में BuildManager का आविष्कार करता है। AddReferencedAssembly()। यह आलेख दिखाता है कि पूर्ण ट्रस्ट और मध्यम ट्रस्ट दोनों में यह कैसे करें: http://shazwazza.com/post/Developing-a-plugin-framework-in-ASPNET-with-medium-trust.aspx। मैं खुद जवाब यहां पोस्ट करूंगा। – lasseschou

0

आप मिल सकती है यह सहायक http://www.adverseconditionals.com/2011/07/portable-aspnet-code-using.html

मैं दो परियोजनाओं

MyLibrary.Templates

.Templates में सामग्री के रूप में दृश्य बनाने MyLibrary और है शुरू कर दिया है, और लिंक के रूप में जोड़ा गया है और करने के लिए सेट MyLibrary में एम्बेडेड संसाधन। जो लोग विचारों को ओवरराइड करना चाहते हैं, वे टेम्पलेट प्रोजेक्ट इंस्टॉल कर सकते हैं।

1

कृपया एनओपीकामर्स स्रोत कोड पर एक नज़र डालें। Shannon द्वारा काम पर आधारित यह अच्छा प्लगइन ढांचा है।

1

आप एमवीसी 3 और 4 में "एरिया" सुविधा के लिए भी जा सकते हैं, आप एक अच्छी प्लगइन प्रणाली बना सकते हैं। यह प्लगइन के मॉडल, देखने और नियंत्रक को अपने स्वयं के असेंबली में संभालने का अलगाव देता है।

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