+90 (507) - 389 61 01

Uygulamanın Bağımlı Olduğu DLL’leri Tek Bir Exe’de Birleştirme

Uygulamanın Bağımlı Olduğu DLL’leri Tek Bir Exe’de Birleştirme

Merhaba,

Hepimiz yazdığımız library’lerde Packaging prensiplerine uyarak, mantıksal olarak farklı işler yapan kod parçalarını ayrı dll’lere (assembly) ayırırız, bu bize reusability açısından büyük avantaj sağlar. Fakat WPF ve ya Winforms uygulamalarında bazen kullandığımız external librarylerin sayısı çok fazla sayıda olabiliyor, sonuç itibariyle hayatımızı kolaylaştıracak, bize vakit kazandıracak yüzlerce library var. Ama çok fazla dll bazen uygulamamızın deployment, güncelleme gibi işlerini oldukça karmaşık hale getirebiliyor. O yüzden uygulamalarımızı tek bir exe haline getirmek isteyebiliriz, böylece uygulamamızı dağıtırken tek bir exe ile uğraşırız.

Bunun için zaten yıllardır ortada olan bir çözüm var. ILMerge’ü çoğunuz biliyordur zaten, çok fazla detaya girmeye gerek yok. ILMerge özetle, sizin seçtiğiniz mevcut assembly’leri birleştirerek, yeni bir assembly oluşturuyor. Bunun bazı dezavantajları var elbette ;

  • Yeni bir assembly oluşturduğundan dolayı orjinal assembly’lerdeki version, culture, public key gibi identityler kayboluyor.
  • WPF uygulamaların da problemlere sebep olabiliyor, çünkü WPF assemby’lerinin identitylerini binary olarak encode ediyor ve ILMerge bunları değiştiremiyebiliyor.

Alternatif yol ise, referans edilecek dll’leri AppDomain’e kendimiz eklemek.

Application Domain kavramına hakim değilseniz buradan bilgi edinebilirsiniz.

Yapmanız gerekenler ;

  • Öncelikle uygulamanızın bağımlı olduğu dll’leri belirleyin.
  • Projenizde bir klasör açın, mesela Dll olabilir.
  • Bağımlı olduğunuz dll’leri referance olarak projenize ekleyin ama Properties kısmından Copy to Output Directory kısmını Do not copy yapın. Zaten kendimiz AppDomain’e runtime’da ekleyeceğiz.
  • Klasör’e bağımlı olduğunuz dll’leri ekleyin ve Properties kısmından bunları Embedded Resource yapın. Ayrıca Solution’da ki Dll projelerinin build outputlarını uygulamadı ki dll klasörüne yönlendirip, uygulamaya referansı bu klasörden eklerseniz güncelleme konusunda rahatlayabilirsiniz.

Uygulamanızın Main methoduna alttaki kodu ekleyin ;

Öncelikle static constructor’da AssemblyResolve event’ine register oluyoruz. LoadAssemblies methodun’da Embedded Resource olarak eklediğimiz dll’leri GetManifestResourceStream yardımıyla alıyoruz. Burada dikkat etmeniz gereken nokta, herangi bir Resource’a ulaşırken “Namespace.Klasör.Resource” şeklinde gitmeniz.

NET 4 ile birlikte AssemblyResolve event’i bütün bulunamayan assembly’ler için tetikleniyor, buna resource’larımızdakiler de dahil. O yüzden yukarıdaki kod’da bir takım kontroller yapmamız gerekebilir.

Gördüğünüz gibi çok kısa bir süre içerisinde yapılabilecek bir işlem, mevcut uygulamanızı kolayca bu hale getirebilirsiniz. Ama dikkat etmeniz gereken nokta AppDomain’e yükleyeceğiniz assembly’nin bağımlı olduğu başka bir assembly varsa onun da AppDomain’e yüklenmesi gerektiği. Eğer birbirine bağlı bu şekilde çok dll’iniz varsa, biraz sıkıntı yaratabilir. Ayrıca elinizde exe yok ve sadece bir kısım Dll’leri merge etmek istiyorsanız bu yöntemle yapmanın ideal bir yolu yok. ILMerge bu anlamda bakarsak daha yetenekli bir tool.

Yukarıda yaptığımız işi otomatize eden belli toollar, Visual Studio Pluginleri var. Mesela Costura gibi, onlara da göz gezdirebilirsiniz.

Bu yöntemin her durum için ideal bir çözüm olduğunu iddaa etmiyorum ama bir çok kişinin derdine derman olacağına inanıyorum :).

Bir sonraki yazımda görüşünceye dek hepinize iyilikler dilerim.

Yorum Yap




Blog Makale Yorumları