Yükleme kodunda belirli bir şey yapmadan bir montaj yüklendiğinde bazı kodların çalıştırılması mümkün mü? Aradığım şey, bir türdeki statik bir kurucu gibi.
Örneğin:
Meclis A, B Kurulumu hakkında bilgi sahibi değildir, fakat B, B hakkında bilgi sahibidir. Montaj A, B yüklüyse, B ile ilgili bazı şeyleri bilmelidir. Assembly B çalışma zamanı tarafından (başvurulan veya açık) yüklendiğinde, Assembly A'da bir yöntemi çağıran bir kod parçası (statik yöntem veya öznitelik) istiyorum.
Bu problemin temel nedeni, ara yüzler kullanıldığında derleme zamanında bilinmeyen B türlerini içeren A türünü serileştirirken, bilinmeyen türlerle karşılaşılır.
CLR destekliyor modül başlatıcılar. Kullanmak için C ++ / CLI kodunu veya ilasm.exe'yi kesmeniz gerekir.
(düzenleme - C ++ için geçerlidir; C ++ yaklaşımı için bkz. bu cevap)
Temel olarak, hayır: yapamazsın. Bu büyük bir saldırı yüzeyi ve izin verilmez. Init kodunun yürütülmesini sağlayan bazı B türlerine statik bir ctor koymak isteyebilirsiniz, ancak bu konuyla ilgili ...
.Net'de statik yapıcılar kullanabilirsiniz, ancak maalesef istediğinizi yapmıyorlar. Statik kurucular sadece bir tür kullanılmadan önce yürütülür. Görmek http://msdn.microsoft.com/en-us/library/k9x6w0hc(VS.80).aspx detaylar için.
AppDomain'in AssemblyLoad olayına abone olmanızdan biraz mesafe alabilirsiniz. Görmek http://msdn.microsoft.com/en-us/library/system.appdomain.assemblyload.aspx.
Olay işleyicinizde yeni yüklenen montajı yansıtabilir ve istediğiniz kodu çalıştırabilirsiniz.
.NET derlemesini başlatmak için 3 seçenek vardır:
- Başlamanız için Meclisinizde Statik bir işlev Init () veya Main () yazarsınız ve bu işlevi, bu Kurulumu yükleyen C # kodundan yansıtarak çağırırsınız.
- Kodunuzu DllMain () içine yerleştirdiğiniz Yönetilen C ++ Derlemesi yazın. Dikkatli olun çünkü kodunuz Loader Lock'da (bazı DLL'lerin yüklenmesi gibi) yasaklanmış olan bazı şeylerin yasaklanmasıyla gerçekleştirilecektir. Ancak, HERHANGİ başlatma işlemini yapan yeni bir konu başlatabilirsiniz. (LoaderLock Hakkında:
https://msdn.microsoft.com/en-us/library/ms173266.aspx) (Hakkında
DllMain'de:
C # C ++ / CLI C DLL System.IO.FileNotFoundException için)
- Saf bir C # derleme derleyin ve burada açıklandığı gibi bir modül başlatıcı kodu eklemek için derlenmiş bir DLL dosyasını değiştirin:
http://einaregilsson.com/module-initializers-in-csharp/
Bu yöntemin dezavantajı, derleme işlemin içine yüklendiğinde başlatma işlevinin hemen çağrılmamasıdır. Ancak mecliste başka bir şeyden önce ilk önce erişilir.
Bu sorunu hafifletmek için muhtemelen serileştirme yaklaşımınızı tekrar gözden geçirmelisiniz. Kullanarak serileştirirseniz
ISerializable ve
SerializableAttribute öznitelik, seri hale getirme grafiğinin, gerektiğinde montaj A olmadan, montaj B'yi açıkça bilmesi gerektiğinde, montaj B'yi yükleyeceği şekilde yapabilirsiniz.
Karma bir montaj kullanarak, DllMain'in bir montaj yükünde çalışmasını sağlayabilirsiniz.