Dinamik Assembly Üretimi (Kodla Dinamik DLL Compile Etmek)

0 dakikada yazıldı

33910 defa okundu

Düzenle

Bir uygulama düşünün kendini programlayabilen. Konumuz “Star Trek” veya
“Geleceğe Dönüş” değil. Emin olun gerçek dünyadan ve yapılabileceklerden
bahsediyorum. Uygulamalarınızın dış sistemlerle ciddi bir bağlantı
içerisinde olduğu durumlarda bazen kendi içlerinde dış sistemlere uygun
kodlar üreterek kullanmaları gerekebilir. Bunu bazen uygulamaların kendi
içlerindeki yapay zeka ile yapabilecekleri gibi bazen ise başka bir dış
kaynaktan aldıkları yeni parametrelerden yola çıkarak kendi kodlarında
değişiklik yapabilirler. Eğer bunların hiçbiri size gerçekçi gelmiyorsa
başka bir seçenek olarak da harici uygulamaların kullanabileceği DLL
dosyaları yaratacak bir uygulama yazmak istediğinizde yapmanız
gerekenlerden bahsedebiliriz. Aslında her ikisi de aynı kapıya çıkıyor.

Bize dinamik olarak uygulamalar tarafından kullanılabilecek DLL
dosyaları yaratacak bir kod lazım. Kullanacağımız nesnelerin çoğunun
bulunduğu esas namespace System.CodeDom.Compiler olacak. Bunun
haricinde C# veya VB için ayrı ayrı uygun namespace’leri kullanmamız
gerek. Eğer VB kodu derleyecekseniz VB sınıflarını C# kodu
derleyecekseniz tabi ki C# sınıflarını kullanmalısınız. Çapraz işlem
yaparak C# kodunuz ile VB kodundan DLL üretme şansınız da var. Biz
örneklerimizde C# ile C#’dan derleme, VB kodu ile de VB’den derleme
yapacağız.

[VB]

Dim KodUretici As New
Microsoft.VisualBasic.VBCodeProvider

Dim Derleyici As System.CodeDom.Compiler.CodeCompiler =
KodUretici.CreateCompiler()

 

Dim Referanslarim As String() = {"System.dll"}

Dim AssemblyAdi As String
= "Ornek.dll"

[C#]

Microsoft.CSharp.CSharpCodeProvider KodUretici = new Microsoft.CSharp.CSharpCodeProvider();

System.CodeDom.Compiler.ICodeCompiler Derleyici =
KodUretici.CreateCompiler();

 

String[] Referanslarim =  {"System.dll"};

String AssemblyAdi= "Ornek.dll";

Kodumuzun başlangıcında ilk olarak birer CodeProvider nesnesi
yaratıyoruz. Elimizdeki hazır kodu derleyecek olan nesneler olarak bu
sınıflar VB ve C# için farklılaşıyor. CodeProvider’lar üzerinden birer
de derleyici nesnesi aldıktan sonra sıra geliyor derleyeceğimiz kodun
referanslarına karar vermeye. Referansları DLL isimleri ile bir
String dizisine aktarmanız şart. Windows uygulamalarında en azından
System.dll’in web uygulamalarında da System.Web.dll’in referans
alınmış olması gerekiyor. Son olarak üreteceğimiz DLL dosyasının adını
da başka bir değişkene aktararak yolumuza devam edelim.

[VB]

Dim DerlemeParametreleri As New
System.CodeDom.Compiler.CompilerParameters(Referanslarim, AssemblyAdi)

DerlemeParametreleri.GenerateExecutable = True

DerlemeParametreleri.GenerateInMemory = False

[C#]

System.CodeDom.Compiler.CompilerParameters DerlemeParametreleri = new
System.CodeDom.Compiler.CompilerParameters(Referanslarim, AssemblyAdi);

DerlemeParametreleri.GenerateExecutable = false;

 DerlemeParametreleri.GenerateInMemory = false;

Derleme işlemini yaparken yapmamız gereken ayarlar var. Bu ayarları
derleyicimize bir CompilerParameters nesnesi olarak aktaracağız.
DerlemeParametreleri değişkenimizi yaratırken referanslarımızı ve
DLL adını aktardıktan sonra özel olarak GenerateExecutable
özelliğini false olarak ayarlıyoruz. Böylece derleyicimiz bize tek
başına çalışabilir bir dosya yaratmaktansa bir DLL dosyası yaratacak.
Bir sonraki adımda da GenerateInMemory özelliğini false yaparak
yaratılacak dosyanın uygulamamız ile aynı konuma, diske yazdırılmasını
sağlıyoruz. Aksi halde yaratılan Assembly sadece hafızada tutulacak
ve diske yazılmayacaktır. Sıra geldi dinamik olarak derlemeyeceğimiz
kodu bir değişkene aktarmaya.

[VB]

Dim Kodum As String
= <Kod>Public
Class Deneme

    Function Metin() As String

        Return "Çalışıyor"

    End Function

End Class</Kod>.Value

[C#]

System.IO.StreamReader Okuyucu = new
System.IO.StreamReader("Class1.cs");

string Kodum = Okuyucu.ReadToEnd();

Okuyucu.Close();

Bu noktada VB ile C# arasında farklı işlemler yaptım. VB’de doğrudan
yaratacağım kodu uygulamanın içerisine gömerken C#’da derleyeceğim C#
kodunu harici bir Class1.cs dosyasından çektim. Siz kendi
uygulamalarınızda ister bu kodları farklı dosyalardan çekin ister metin
işlemleri ile dinamik kod yaratın. İhtiyaçlarınıza göre uygun çözümü
üretmek tamamen size kalmış. Önemli olan tek nokta aslında bu kodlarda
hiçbir hatanın olmaması gerektiği, aksi halde derleme işlemi
yapılamayacaktır.

[VB]

Dim Sonuc As System.CodeDom.Compiler.CompilerResults =
KodUretici.CompileAssemblyFromSource(DerlemeParametreleri, Kodum)

[C#]

System.CodeDom.Compiler.CompilerResults Sonuc =
KodUretici.CompileAssemblyFromSource(DerlemeParametreleri, Kodum);

Tüm ayarlarımız tamamlandığında göre doğrudan CodeProvider
nesnemizin CompileAssemblyFromSource metodunu kullanarak derleme
işlemini başlatabiliriz. Tabi bu esnada daha önce hazırlamış olduğumuz
DerlemeParametrelerini de metoda parametre olarak aktarıyoruz.
Derleme işlemimizi baştan sona tamamlayan kodumuzu bir bütün olarak
inceleyelim.

[VB]

Dim KodUretici As New
Microsoft.VisualBasic.VBCodeProvider

Dim Derleyici As System.CodeDom.Compiler.CodeCompiler =
KodUretici.CreateCompiler()

 

Dim Referanslarim As String() = {"System.dll"}

Dim AssemblyAdi As String
= "Ornek.dll"

 

Dim DerlemeParametreleri As New
System.CodeDom.Compiler.CompilerParameters(Referanslarim, AssemblyAdi)

        DerlemeParametreleri.GenerateExecutable = True

        DerlemeParametreleri.GenerateInMemory = False

 

Dim Kodum As String
= <Kod>Public
Class Deneme

    Function Metin() As String

        Return "Çalışıyor"

    End Function

End Class</Kod>.Value

 

Dim Sonuc As System.CodeDom.Compiler.CompilerResults =
KodUretici.CompileAssemblyFromSource(DerlemeParametreleri, Kodum)

[C#]

Microsoft.CSharp.CSharpCodeProvider KodUretici = new Microsoft.CSharp.CSharpCodeProvider();

System.CodeDom.Compiler.ICodeCompiler Derleyici =
KodUretici.CreateCompiler();

 

String[] Referanslarim =  {"System.dll"};

String AssemblyAdi= "Ornek.dll";

 

System.CodeDom.Compiler.CompilerParameters DerlemeParametreleri = new
System.CodeDom.Compiler.CompilerParameters(Referanslarim, AssemblyAdi);

DerlemeParametreleri.GenerateExecutable = false;

DerlemeParametreleri.GenerateInMemory = false;

 

System.IO.StreamReader Okuyucu = new
System.IO.StreamReader("Class1.cs");

string Kodum = Okuyucu.ReadToEnd();

Okuyucu.Close();

 

System.CodeDom.Compiler.CompilerResults Sonuc =
KodUretici.CompileAssemblyFromSource(DerlemeParametreleri, Kodum);

Dinamik olarak DLL dosyası derlemek işte bu kadar kolay. Dinamik kod
yaratma araçları son dönemde çok popüler. Veritabanına bağlanarak
veritabanındaki nesneleri algılayıp uygun “Veri Katmanı” kodunu dinamik
olarak oluşturan hazır uygulamalar olduğu gibi bazı durumlarda özel
kodlar yazmak da gerekebiliyor. Böyle bir durumda artık siz de
uygulamalarınıza farklı kaynaklardaki şartlara uygun kodu dinamik olarak
üretebilir ve bir DLL olarak farklı uygulamalara aktarabileceğiniz gibi
kendi uygulamalarınızda da kullanabilirsiniz. Yarattığınız DLL dosyasını
hemen uygulamanızda kullanmak isterseniz bu sefer dinamik olarak
Assembly kullanımını ve Reflection konusuna eğilmenizde fayda var.

Hepinize kolay gelsin.