2009-12-04 23 views
20

मैं एमईएफ का उपयोग करके चीजें करने के लिए कुछ समय की कोशिश करता हूं लेकिन अब, मैं एक समस्या में भाग लेता हूं, मुझे मदद चाहिए।आयात संपत्ति हमेशा शून्य (एमईएफ आयात मुद्दा)

विवरण: मेरे पास 2 डीएलएल और एक EXE फ़ाइल है। ClassLibrary1 (LoggerImpl.cs, SomeClass.cs) ClassLibrary2 (ILogger.cs) WindowsApplicationForms1 (WindowsApplicaitonForms1.cs, Program.cs)

मैं कोई मदद या दिशा क्यों यह काम नहीं करता है? (नई SomeClass())

// ClassLibrary1.dll 
//SomeClass.cs 
public class SomeClass 
    { 
     [Import("Logging", typeof(ILogger))] 
     public ILogger Log { get; set; } <-- ALWAYS NULL ??? 

     public void Print() 
     { 
      Log.Print(); 
     } 

    } 

// ClassLibrary1.dll 
// LoggerImpl.cs 
namespace ClassLibrary1 
{ 
    [Export("Logging", typeof (ILogger))] 
    public class LoggerImpl : ILogger 
    { 
     public void Print() 
     { 
      Console.WriteLine("print called"); 
     } 
    } 
} 

// ClassLibrary2.dll 
// ILogger.cs 
namespace LogNamespace 
{ 
    public interface ILogger 
    { 
     void Print(); 
    } 
} 

// WindowsFormsApplication1.exe 
// WindowsFormsApplication1.cs 
namespace WindowsFormsApplication1 
{ 
    [Export("Form1",typeof(Form1))] 
    public partial class Form1 : Form 
    { 

     [Import("Logging", typeof(ILogger))] 
     public ILogger Log { set; get; } 

     private CompositionContainer _container; 

     public Form1() 
     { 
      InitializeComponent(); 
      Compose(); 
      Log.Print(); 

      SomeClass c = new SomeClass(); 
      c.Print(); 
     } 

     private void Compose() 
     { 
      var catalog = new AggregateCatalog(); 

      catalog.Catalogs.Add(new DirectoryCatalog(".")); 
      catalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly())); 
      _container = new CompositionContainer(catalog); 

      try 
      { 
       _container.ComposeParts(this); 
      } 
      catch (CompositionException compositionException) 
      { 
       MessageBox.Show(compositionException.ToString()); 
      } 
     } 
    } 
} 
+2

आपका 'तो इसके आयात सेट किया जा कभी नहीं होगा SomeClass', संरचना में शामिल नहीं है। – dtb

उत्तर

27

में शामिल करने के लिए निम्न के समान की तरह एक बयान की जरूरत है, कंटेनर इसके बारे में कुछ भी नहीं पता होगा और इसे लिख नहीं पाएगा।

एमईएफ द्वारा तैयार किए जाने वाले एक हिस्से के लिए, इसे एमईएफ द्वारा बनाया जाना चाहिए, या कंटेनर को स्पष्ट रूप से पारित किया जाना चाहिए। आप मैन्युअल रूप से MEF बता उसी तरह से SomeClass वस्तु के आयात को पूरा करने के कर सकते हैं आप इसे बताया प्रपत्र के आयात को पूरा करने के:

SomeClass c = new SomeClass(); 
_container.SatisfyImports(c); 
c.Print(); 

हालांकि, अगर आप ऐसा करने के लिए कंटेनर के लिए सीधी पहुँच की जरूरत है, तो यह काम नहीं करता है साथ ही आपके फॉर्म 1 कक्षा के बाहर। सामान्य तौर पर, यह करने के लिए एक बेहतर तरीका SomeClass के लिए अपने Form1 वर्ग में SomeClass निर्यात करने के लिए, और बनाने के एक आयात होगा:

[Export] 
public class SomeClass 
{ 
    [Import("Logging", typeof(ILogger))] 
    public ILogger Log { get; set; } 

    // etc. 
} 

public partial class Form1 : Form 
{ 
    [Import("Logging", typeof(ILogger))] 
    public ILogger Log { set; get; } 

    [Import] 
    SomeClass _someClass { get; set; } 

    // etc. 
} 
+0

+1। प्राथमिक मुद्दा कुछ क्लासस में संरचना कंटेनर नहीं है। यदि SomeClass को एक इंटरफ़ेस में ही बदल दिया गया था, तो एक आईनेमेरेबल (उदाहरण के लिए) आयातमनी विशेषता के साथ उपयोग किया जा सकता है ताकि यह निर्देशिका कोड/ओ अतिरिक्त कोड में असेंबली छोड़कर भागों को जोड़ने का एक बहुत ही सरल तरीका बन जाए। – JamesEggers

1

आप आप एक वर्ग अपने आप को एक नया उदाहरण बनाते हैं SomeClass रचना प्रक्रिया

// ClassLibrary1.dll 
//SomeClass.cs 
using System; 
using System.ComponentModel.Composition; 
using System.ComponentModel.Composition.Hosting; 
using System.Windows.Forms; 
using LogNamespace; 

public class SomeClass 
{ 
    [Import("Logging", typeof(ILogger))] 
    public ILogger Log { get; set; } //<-- ALWAYS NULL ??? 

    public SomeClass() 
    { 
     var catalog = new AggregateCatalog(); 
     CompositionContainer _container; 

     // catalog.Catalogs.Add(new DirectoryCatalog(".")); 
     catalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly())); 
     _container = new CompositionContainer(catalog); 

     _container.ComposeParts(this); 
    } 

    public void Print() 
    { 
     Log.Print(); 
    } 

} 

// ClassLibrary1.dll 
// LoggerImpl.cs 
namespace ClassLibrary1 
{ 
    [Export("Logging", typeof(ILogger))] 
    public class LoggerImpl : ILogger 
    { 
     public void Print() 
     { 
      Console.WriteLine("print called"); 
     } 
    } 
} 

// ClassLibrary2.dll 
// ILogger.cs 
namespace LogNamespace 
{ 
    public interface ILogger 
    { 
     void Print(); 
    } 
} 

// WindowsFormsApplication1.exe 
// WindowsFormsApplication1.cs 
namespace WindowsFormsApplication1 
{ 
    [Export("Form1", typeof(Form1))] 
    public partial class Form1 : Form 
    { 

     [Import("Logging", typeof(ILogger))] 
     public ILogger Log { set; get; } 

     private CompositionContainer _container; 

     public Form1() 
     { 
      InitializeComponent(); 
      Compose(); 
      Log.Print(); 

      SomeClass c = new SomeClass(); 
      c.Print(); 
     } 

     private void Compose() 
     { 
      var catalog = new AggregateCatalog(); 

      // catalog.Catalogs.Add(new DirectoryCatalog(".")); 
      catalog.Catalogs.Add(new AssemblyCatalog(System.Reflection.Assembly.GetExecutingAssembly())); 
      _container = new CompositionContainer(catalog); 

      try 
      { 
       _container.ComposeParts(this); 
      } 
      catch (CompositionException compositionException) 
      { 
       MessageBox.Show(compositionException.ToString()); 
      } 
     } 
    } 
} 
+0

प्रतिक्रिया के लिए धन्यवाद। तो यदि मैं भागों के साथ एक और डीएलएल जोड़ता हूं, तो मुझे उन हिस्सों को शामिल करने के लिए क्लाइंट कोड (कंपोज़ विधि पढ़ें) को भी बदलना होगा? मैं सोच रहा था कि यदि मैं एक और भाग बनाता हूं और ऐप के साथ निर्देशिका में डालता हूं, तो एप्लिकेशन उस भागों का उपयोग कर सकता है यदि ऐप में उचित आयात (जैसे, मेनी, लॉगर, टूलबार इत्यादि) शामिल हैं। – ITGoran

+2

इस कोड में आप दो अलग कंटेनर बना रहे हैं, जो शायद आप नहीं चाहते हैं। दो कंटेनर के साथ, आपको अपने फॉर्म 1 क्लास और आपके SomeClass में लॉगर के दो अलग-अलग उदाहरण मिलेंगे। –

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