C# - Web szerviz által szolgáltatott assembly felhasználása

forráskód letöltése
A Webes megoldások változatai közül a Web szervizek is egyre nagyobb arányban vannak jelen a szervereken. Előnyük, hogy saját alkalmazásainkból is elérhetjük metódusaikat, anélkül, hogy ismernénk annak kódját. Cikkünkben bemutatunk egy példát arra, hogy miként hívható meg egy adott dinamikus könyvtár függvénye, amelynek kódját egy szerviz szolgáltatja. A metódus meghívásához igénybe vesszük a szerviz nyilvános függvényét.
Mellékelt példa megnyitása előtt szükséges egy Service nevű virtuális könyvtár létrehozása, mely a példa mappájában található Service alkönyvtárra mutat. Ehhez nyissa meg a mappa Tulajdonság ablakát és itt a Webmegosztás lapon engedélyezze a mappa megosztását olvasási és parancsfájlok futtatási jogával.
A kliens alkalmazás futtatása előtt gondoskodnunk kell arról, hogy a Web szerver virtuális mappájában engedélyezzük a névtelen hozzáférést.
A mellékelt példa három projektet tartalmaz. A Client és a Service projektek tartalmazzák a szerviz és az azt elérő Windows-os alkalmazás kódját. A ServiceCode projekt pedig annak a Form-nak a kódját tartalmazza, mely megjelenik a kliens alkalmazás gombjára történő kattintáskor.
A példa lényege, hogy a szerviz alkalmazás kódját tartalmazó mappában van a ServiceCode.dll állomány elhelyezve. A kliens alkalmazás meghívja a szerviz GetFormCode metódusát, melynek eredménye egy string tömb, benne többek közt az assembly kódja bináris formátumban.
A kód eljut a klienshez, majd a bináris adathalmaz felhasználásával megjelenítjük az űrlapot.
Megjelenítendő Form kódja
A ServiceCode projekt egy űrlap kódja, mely csupán egy nyomógombot tartalmaz, melyre kattintva bezárhatjuk az űrlapot, valamint egy szövegmezőt, melyben megjelenik a hívó űrlapról átadott név.
A Form1 osztályban definiálunk egy metódust RunDlg néven, mely megjeleníti a Form-ot. Ennek paramétere a megjelenítendő karakterlánc.
public void RunDlg(string name)
{
  textBox1.Text = name;
  this.ShowDialog();      
}
A generált kód egy DLL lesz, nem pedig EXE, így a Main függvény kódját eltávolíthatjuk.
Szerviz alkalmazás
A szerviz alkalmazásban a GetFormCode metódus adja vissza a felhasználandó kódot. A visszaadott karakterlánc-tömb tartalmazza a DLL nevét, az osztály nevét, melyben definiáltuk a RunDlg metódust, és a metódus neve.
A tömb negyedik eleme a DLL bináris kódja, mely eljut a klienshez.
string[] datas = new string[4];
datas[0] = "ServiceCode.dll";
datas[1] = "ServiceCode.Form1";
datas[2] = "RunDlg";
A kód beolvasása a FileStream osztály segítségével történik.
string path = Server.MapPath("bin") + "//ServiceCode.dll";
FileStream codedll = new FileStream(path,FileMode.Open,FileAccess.Read);
byte[] b = new byte[codedll.Length];
codedll.Read(b,0,(int)b.Length);
...
datas[3] = Convert.ToBase64String(b,0,(int)b.Length);
Kliens alkalmazás
A kliensben egy Webes referencia hozzáadásával hozzuk létre a szerviz eléréséhez szükséges proxy-t. Ennek eredményeképpen a Reference.cs állományban lesz megtalálható a proxy deklarációja. Az alkalmazás gombjára történő kattintáskor ezt példányosítjuk, majd meghívjuk a szerviz metódusát.
localhost.CodeService cs = new localhost.CodeService();
string[] lines = cs.GetFormCode();
A kapott tömböt fel kell dolgoznunk. Először kinyerjük a DLL kódját.
byte[] b = Convert.FromBase64String(lines[3]);
Majd ebből létrehozunk egy Assembly objektumot.
Assembly a = Assembly.Load(b);
Létrehozzuk az osztálynév alapján a típust.
Type t = a.GetType(lines[1]);
Létrehozunk a RunDlg metódus számára egy MethodInfo objektumot.
MethodInfo info = t.GetMethod(lines[2]);
Létrehozunk egy példányt a Form1 osztályból.
Object o = Activator.CreateInstance(t);
A RunDlg metódus paramétere számára létrehozunk egy objektum-tömböt.
Object[] ps = new Object[]{listBox1.SelectedItem};
És meghívjuk a metódust.
info.Invoke(o,ps);
A megjelenő Form gombjára kattintva már meghívódik a Form kódjában deklarált kezelőfüggvény, mely bezárja a panelt.