2013-04-22 26 views
10

MEF Çalışma Zamanı Eklentisi Güncelleştirme Sayı

Sorunum

MEF kodum, derlemeler sırasında bir dizin klasörüne ilişkilendirilmiş bir klasörden uygun şekilde güncelleştirme yapılamıyor. Eklentiler, çalışma zamanında başarılı bir şekilde yüklenir, ancak dll'yi güncellediğimde ve DirectoryCatalog'da Yenile'yi çağırdığımda, derlemeler güncellenmez.

Arka plan

Bir MEF kabı olan bir dll oluşturuyorum ve bir yerel eklenti klasörü bulmak için bir DirectoryCatalog kullanır. Ben şu anda basit bir WinForm gelen dll, bu benim eklenti klasöründeki dlls üzerine yazabilmek için ayrı bir proje ile ShadowCopy kullanmak için kurulum olarak adlandırıyorum. Bu klasörü güncelleştirmek için bir FileWatcher kullanmak yerine, DirectoryCatalog'da yenileme çağrıları yapan bir kamu yöntemini açığa çıkarıyorum, böylece derlemeleri otomatik olarak yerine otomatik olarak güncelleyebilirim.

Kod

temel sınıf MEF katalog ve konteyner başlatır ve referans erişim için sınıf değişkenler olarak kaydeder sonra

public class FieldProcessor 
{ 
    private CompositionContainer _container; 
    private DirectoryCatalog dirCatalog; 

    public FieldProcessor() 
    { 
     var catalog = new AggregateCatalog(); 
     //Adds all the parts found in the same assembly as the TestPlugin class 
     catalog.Catalogs.Add(new AssemblyCatalog(typeof(TestPlugin).Assembly)); 
     dirCatalog = new DirectoryCatalog(AppDomain.CurrentDomain.BaseDirectory + "Plugin\\"); 
     catalog.Catalogs.Add(dirCatalog); 

     //Create the CompositionContainer with the parts in the catalog 
     _container = new CompositionContainer(catalog); 
    } 

    public void refreshCatalog() 
    { 
     dirCatalog.Refresh(); 
    } 

} ... 

burada ben üzerine çalışıyorum eklenti bulunmaktadır. Güncelleme sınaması, döndürülen sokmaların bir metin kutusuna verilmiş olması, eklentinin döndüğü Dizeleri değiştirmem, yeniden oluşturma ve eklenti klasörüne kopyalamamdır. Ancak, uygulamayı kapatıp yeniden başlatana kadar çalışan uygulama için güncellenmiyor.

[Export(typeof(IPlugin))] 
[ExportMetadata("PluginName", "TestPlugin2")] 
public class TestPlugin2 : IPlugin 
{ 
    public IEnumerable<IField> GetFields(ContextObject contextObject, params string[] parameters) 
    { 
     List<IField> retList = new List<IField>(); 
     //Do Work Return Wrok Results 
     retList.Add(new Field("plugin.TestPlugin2", "TestPluginReturnValue2")); 
     return retList; 
    } 
} 

Düzenleme Bir kaba bir DirectoryCatalog ekleyip kaydetmek için, makale ve cevap olarak görünmektedir kod örnekleri her yerde oldukça kapsamlı araştırmalar yaptık ve adres

İthalat Bildirimi

[ImportMany(AllowRecomposition=true)] 
    IEnumerable<Lazy<IPlugin, IPluginData>> plugins; 

Araştırma Bu kataloğun bir referansı, daha sonra yeni bir eklentinin arısı eklendikten sonra bu referansta Yenile'yi çağırın ve yaptığım derlemeleri güncelleyecektir, ancak bu yeni eklenti dll'den güncellenmiş çıktıyı göstermeyecektir.

İstek

Bu sorunu gören var mı, yoksa çalışma zamanlarında güncelleştirme yapmayan derlemelerdeki sorunlara neden olabilir mi? Herhangi bir ek bilgi veya içgörü takdir edilecektir.

Çözünürlük

Panos ve Stumpy sayesinde bağlantılarıma çözümümün nedenini yolladı. Gelecekte bilgi arayanlar için temel sorun, Yenileme yönteminin derlemeleri, yeni derlemenin üzerine yazılan dll ile aynı montaj adını verdiğinde güncellenmemesiydi. Benim POC'im için, montaj ismine ve her şeyin aynısına eklenen bir Tarih ile yeniden inşayı test ettim ve bir çekicilik gibi çalıştı. Aşağıdaki yorumlardaki bağlantıları çok yararlıydı ve aynı sorunu yaşıyorsanız tavsiye edilir.

+1

DirectoryCatalog.Refresh olacak

DirectoryCatalog meclisleri, sadece eklenen veya kaldırılan güncellemez güncellenmiş assebmlies'ı algılamıyor. Sadece yeni veya silinmiş olanlar. Bir geçici çözüm ve öneriler için bu cevaba bir göz atın: http://stackoverflow.com/a/14842417/850119 –

+0

Yüklerim yüklendiklerinde kilitlenirler, böylece onları yeni dll'lerle geçersiz kılamam. Bu problemin yok muydu? Onları güncellenebilir yapan bir şey yaptın. –

+0

Evet, bu sorunla karşılaştım. Geçişte bahsettiğim adımlardan biri "Gölge Kopyası" nı etkinleştirmekti. Gölge Kopyası, bir programın dll derlemelerinin yerel kopyalarını çekmesine ve bunları dll'leri kilitlemek yerine yerel bir önbelleğe eklemesine izin verir. Bu, çalışma sırasında "hot swap" dll'lerine izin vermek için etkinleştirilmelidir, aksi takdirde programı durdurmanız, dll'leri değiştirmeniz ve sonra yeniden başlatmanız gerekir. Sanırım baktığım örnek bu, ama google MEF ve Shadow Copy için çalışmıyorsa, http://stackoverflow.com/questions/12593308/mef-and-shadowcopying-dlls-so-that-i -can-overwrite-onları-at-çalışma zamanı – Madullah

cevap

3

AllowRecomposition parametresini Alma özniteliğinize ayarladınız mı?

AllowRecomposition 
Gets or sets a value that indicates whether the property or field will be recomposed when exports with a matching contract have changed in the container. 

http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.importattribute(v=vs.95).aspx

düzenleme: etrafında bir iş için http://msdn.microsoft.com/en-us/library/system.componentmodel.composition.hosting.directorycatalog.refresh.aspx

: https://stackoverflow.com/a/14842417/2215320

+0

yaptım, üzgünüm ben ithalat deyim kodu başlangıçta göndermedim, ben ithalat beyanımı yansıtmak için soru güncelledik. – Madullah

+0

ve yenileme kodunuz? Sanırım sorun içeride. FileSystemWatcher kullanmadığını söylemiştiniz, montajlarınızı nasıl tespit edip yeniden yüklersiniz? – Niels

+0

Yukarıda görülen RefreshCatalog yöntemini kullanarak açığa çıkıyorum. Bu yöntemi bir winForm üzerindeki bir düğme tıklama olayından arıyorum. – Madullah

İlgili konular