Saturday, November 12, 2005

שלום לכולכם,

כולנו עובדים עם Assemblies (להלן: אסמבליס ברבים, אסמבלי ביחיד). גם אם אתמול התחלתם לעבוד בדוט נט ובניתם רק אפליקציה לדוגמה - אתם עבדתם עם אסמבלי.  בואו כולנו נפתח עכשיו Visual studio, נבחר לפתוח פרוייקט חדש ונקמפל (נעשה build). מה שכרגע קרה זה שהקומפיילר בנה לכם אסמבלי. אם בנינו אפליקציית web אז קיבלנו בספריית ה-bin קובץ myProject.dll, ואם בנינו אפליקציית winform/console נקבל בספריית ה-bin קובץ myProject.exe.

א. מהן אסמבליס?

אסמבליס הן אבני הבנייה הבסיסיות בדוט נט אשר ניתן לפרוס ויוצרות תיחום של אבטחה, גרסאות, טיפוסי נתונים והפנייה הדדית כל זאת באמצעות תיאור עצמי.
אם לא הבנתם את המשפט הזה, אל תדאגו, הכל יהיה ברור.

דיברנו בנפנוף-ידיים על איך מקבלים אסמבלי, אז בואו נדבר על זה עוד קצת.כל קוד בדוט נט ללא שייכות לשפת התכנות מתקפל בסופו של דבר לקוד MSIL. קוד ה-MSIL הזה יושב בתוך קבצי PE (גם: Portable executable). אל תדאגו אם בחיים לא ראיתם כזה סוג קובץ, אם אתם עובדים עם Visual studio.net סביר להניח שבחיים גם לא תראו. הקבצי PE הללו שמכילים קוד MSIL בחיים לא יוכלו לרוץ אלא אם כן הם יהיו קשורים ל-Assembly manifest (להלן: מניפסט). אותם קבצי PE כברירת מחדל אינם מכילים מניפסט.

עוד חלק מהאסמבלי הוא ה-Type metadata. באנגלית Metadata זה - מידע שמתאר מידע. אז Type metadata זה מידע שמתאר טיפוסים. ב-#C טיפוסי נתונים הם המחלקות השונות שלנו. כלומר, Type metadata זה המידע שמתאר את המחלקות השונות שלנו. ה-Type metadata מכיל ממש את ה"כותרות" של המחלקה: האירועים שהמחלקה חושפת, המשתנים הפנימיים, ה-Properties שהמחלקה חושפת, המתודות של המחלקה (והפרמטרים שהיא מקבלת ומחזירה, האם היא סטטית או לא), ומאיזה מחלקה הטיפוס יורש. הנ"ל גם תקף לכל חלק אחר מה-assembly שיורש מ-System.object ולא רק למחלקות, למשל גם לממשקים ול-Enums.

פתחתי את כלי ה-ilsdam, שנותן לנו לבחון אסמבלי לאחר שהתקמפלה (כמו ה-Reflector המפורסם, רק יותר מאותגר ומגיע עם הפריימוורק). בחרתי להביט על System.dll והתחלתי לדפדף בפנים:

Assembly1.gif

כל זה  (יותר נכון הרוב) זה Type metadata. בתמונה לעיל אפשר לראות כאן פרטים של מחלקת System.Timers.Timer. הכל נמצא כאן: החל ממשתנים פנימיים, Properties שהמחלקה חושפת, מתודות שהמחלקה חושפת (עם הפרמטרים שהיא מקבלת ומחזירה), המחלקה ממנה היא יורשת, הממשקים שאותה היא מממשת ועוד. כל זה הוא ה-Type metadata.

קבצי ה-PE שהזכרנו קודם לכן מכילים שלושה חלקים: נקודת כניסה (PE header), קוד MSIL, וה-Metadata של האובייקטים בקובץ. ה-Metadata של האובייקטים שלנו בתוך האסמבלי למעשה נשמר בתוך קבצי ה-PE.

אז אם נחשוב לרגע על איך פועלים למעשה כל ה-Reflectorים וה-ildasmים למיניהם שהם מראים לנו כזה תפריט ניווט. הם לא פותחים את קוד ה-MSIL בתוך האסמבלי, הם רק קוראים את המידע מתוך ה-metadata ומציגים לנו אותו כמו שהוא. עד כאן עם Type metadata. (אגב, רק לתת דוגמה עד כמה מסובך כל הסיפור הזה, בשפות כמו VB.net ו-#C יש הגבלה להורשה ממחלקה אחת בלבד, אבל ה-Type metadata גם יודע למשל לתאר הורשה ממספר מחלקות).

עוד חלק מכל אסמבלי הוא ה-Resources (להלן: משאבים). המשאבים הנפוצים של אפליקציות הם קבצים שגררנו לתוך עץ הפרוייקט ב-Visual studio (כגון תמונות וקבצי טקסט), ובנוסף משאבים שאחראים על שינוי תצוגה לתרבויות שונות. נציג כאן דוגמה של הראשון - קובץ תמונה בתוך פרוייקט. נגרור תמונה לתוך עץ הפרוייקט ב-visual studio ונרצה לראות שהוא באמת בתוך האסמבלי שלנו ולא בתוך איזו תיקייה מסתורית איפהשהו על ההארד-דיסק. איתרע מזלנו וה-ildasm אינו תומך בהצגת משאבים, אז נשתמש ב-Reflector:

Assembly2.gif

והנה, אנו יכולים לראות באמצעות ה-reflector שבאמת בתוך ה-Reflector קיים קובץ התמונה שגררתי לתוך הפרוייקט. שאר הקבצים בתוך ספריית ה-Resources הם כמו שהזכרתי קבצים שיוצרו אוטומטית ע"י Visual studio למקרה ונרצה לשנות תכונות של האפליקציה בהתאם לתרבות בה היא מורצת (למשל, אם נרצה שבתרבות הישראלית-עברית ניתן יהיה להגדיל חלון ותרבות הצרפת-צרפתית לא יהיה ניתן).

אז מה יש לנו עד עכשיו בתוך אסמבלי: קבצי PE עם קוד MSIL, משהו בלתי מוכר בשם מניפסט, Type metadata, ומשאבים.

המניפסט של האסמבלי הוא החלק שנותן לכל אמסבלי את היכולת לתאר את עצמה. הוא גם אגב, החלק היחידי מבין ארבעת החלקים שראינו שחובה שיהיה בכל אסמבלי באשר היא. המניפסט של האסמבלי הוא למעשה מה שמחבר את כל החלקים השונים יחדיו ונותן להם שורה וצורה משותפת.

המניפסט מכיל מידע על כל הקבצים שהם חלק מהאסמבלי, ובפרט: קבצי ה-PE המכילים קוד MSIL, והמשאבים השונים. כלומר, זה לא מספיק שרק נוסיף קוד או משאב לתוך האמסבלי, אלא צריך גם להוסיף אותם לאיזה אינדקס שאומר למעשה "אני כאן".

בנוסף המניפסט מכיל שני הפניות חשובות: Type metadata reffrence ו-Assemblies reffrence. ה-Type metadata reffrence משמש להגיד למי שטוען את האסמבלי "במקום הזה והזה תוכל למצוא את טיפוסי הנתונים שאיתם אני עובד". לרוב ה-Type metadata reffrence יפנה על האסמבלי עצמה ל-Type metadata שהיא חלק מהאסמבלי. בתקופה שלפני דוט נט שכולנו עבדנו רכיבי Com היו המון בעיות סנכרון של רכיבים מול ה-Type libaries שלהם. למזלנו, כברירת מחדל האסמבלי מכילה את המידע שמתאר את הטיפוסים איתה היא עובדת. (רוב המקרים בדוט נט בהם ה-Type metadata reffrence לא יפנה לאסמבלי עצמה היא באמת בעבודה עם רכיבים מהדור הישן).
ה-Assemblies reffrence גם מאוד חשוב. הוא זה שבא ואומר לאיזה אסמבליס אחרים האסמבלי הזו קשורה. למשל, אם אנחנו כתבנו קוד שמצייר פרח על המסך, כאשר נקמפל את הקוד אנו נקבל כחלק מהמניפסט הפנייה ל-System.Drawing.
עוד משהו שהמניפסט מכיל הוא מידע שמזהה את האמסבלי - שם האסמבלי, גירסת האסמבלי, התרבות אליה שייכת האסמבלי ומפתח. כל אלו ביחד נקראים Strong name. עוד נדבר על הנושא הזה בהמשך. אבל כרגע נזכור שלכל אסמבלי יש את ארבעת הנתונים הללו במניפסט שלה, ואם לא הגדרנו אותם הם מקבלים ערכי ברירת מחדל.

בוא נסכם מה מכילה כל אסמבלי:

1.  קבצי PE המכילים קוד MSIL. זה למעשה הקוד המקומפל אותו כתבנו.

2. Type metadata. זה למעשה תיאור כל האובייקטים בכלל וכל מחלקות בפרט. (צריך לזכור שהמידע הזה לרוב יושב בתוך קבצי ה-PE שלנו)

3. משאבים. קבצים חיצוניים שנשמרו לתוך האסמבלי.

4. מניפסט האסמבלי (חובה) שמכיל את: רשימת קבצי ה-PE והמשאבים באסמבלי, Type metadata reffrence שלרוב יצביע בחזרה על ה-type metadata מסעיף 2, Assemblies reffrence שיצביע על שאר האסמבליס בהן תלויה האסמבלי שלנו, וארבעת נתוני ה-Strong name.  

 

ב. הדגמה מעשית, היתרונות של אסמבליס (אבטחה והפנייה הדדית)

"אסמבליס הן אבני הבנייה הבסיסיות בדוט נט אשר ניתן לפרוס ויוצרות תיחום של אבטחה, גרסאות, טיפוסי נתונים והפנייה הדדית כל זאת באמצעות תיאור עצמי."

עד עכשיו הרחבנו מה זה "תיאור עצמי" של אסמבליס. בחלק זה נתמקד בנושא האבטחה וההפנייה ההדדית.

בואו ניצור פרוייקט לדוגמה שהוא Class libary של מחשבון שמקבלת שתי מספרים ומחזירה את התוצאה.

Assembly3.gif

יצרנו מחלקה חדשה בשם Calc עם קונסטרקטור ריק ומתודת Add שמחברת שני מספרים ומחזירה אותם. בנינו את הפרוייקט ונראה שאכן קיבלנו אסמבלי:

Assembly4.gif

הקובץ DLL שקיבלנו הוא הדוט נט אסמבלי שלנו. הקובץ השני למי שמתעניין הוא קובץ למטרות Debug של האפליקציה ולא קשור ישירות לנושא שלנו.

נבנה אפליקציה חלונאית חדשה שתייצג את המחשבון שלנו:

Assembly5.gif

אך אבוי! אין לנו את היכולת לדעת מה הסכום של שני מספרים! (לכו איתי עם זה, תעמידו פנים)
אנחנו חייבים לקשר לאסמבלי שבנינו קודם לכן.

ניכנס לתפרט Reffrences ונבחר Add reffrence:

Assembly6.gif

נביט על רשימת ה-Assembly reffrence שלנו ונראה את רשימת האסמבליס אשר להן קשורה האסמבלי שלנו:

Assembly7.gif

בואו נבנה את הפרוייקט ונראה שבאמת קיבלנו אסמבלי גם לאפליקציית EXE שלנו בתייקת ה-bin שלו:

Assembly8.gif

בואו נחזור לרשימה הזאת שראינו קודם לכן. היה שם למשל את האסמבלי של System.Windows.Forms. כל אפליקציה חלונאית חייבת לכלול Assembly reffrence ל-System.Windows כדי להשתמש ב-Windows controls. כמו כן ראינו הפנייה ל-System אסמבלי, כל אסמבלי באשר היא תכלול הפנייה ל-System. גם ראינו שיש הפנייה ל-Justin_calc שבנינו קודם לכן. בואו נפנים לרגע מה זה אומר - כל אסמבלי מכילה ויודעת לאיזה אסמבליס אחרות היא קשורה.

אבני-יסוד שבנויות ומסתמכות על אבני-יסוד אחרות.


בואו נדבר קצת על אבטחה. כל אסמבלי לפני שהיא רצה מc:\Inetpub\WinCalc\AssemblyInfo.csבקשת הרשאות ממערכת הפעלה ומהפריימוורק על אותו מחשב. ההרשאות האלו מגוונות וכוללות למשל: הרשאה לצייר על המסך, הרשאה להדפיס למסך, הרשאה לכוננים, הרשאה לגשת לאינטרנט, הרשאה לפתוח קישורים למסדי נתונים וכך הלאה. כל ההרשאות הללו יושבות ב-System.Security ודורשות מאמר בפני עצמו. האסמבלי שהיא נטענת לזכרון מבצעת שלושה בקשות: מינימום הרשאות כדי לרוץ, הרשאות אופציונליות כדי לרוץ והרשאות שאסור לאסמבלי לקבל.

האסמבלי שהיא נטענת תבוא ותבקש: "תתן לי בבקשה את כל ההרשאות המינימליות שלי והאופציונליות שלי, ואל תתן לי את ההרשאות האסורות שלי". הפריימוורק ירוץ ויבדוק מול ה-Security policy של הארגון, המחשב והמשתמש ויבדוק אם התוכנה אמורה לקבל את ההרשאות האלו ובהתאם יעניק או יסרב.

שימו לב מה קורה, האסמבלי מבקשת גם הרשאות מינימליות וגם אופציונליות. ההרשאות האופציונליות של כל אסמבלי הן כל ההרשאות. כלומר, כל אסמבלי תבקש גישה לכל ההרשות לרוץ אבל מה - רק כאופציה. אז מה אם בכלל אני יכול לכתוב תוכנת שרת-לקוח שחייבת גישה לרשת, הגישה לרשת שלי תהיה אופציונלית בלבד. אם ה-Security policy של הארגון, המחשב או המשתמש יחליטו שאין לי גישה - אין לי גישה.

מפתחים מנוסים וחדשים כאחד לרוב לא מודעים לזה. למה? הם מפתחים על מחשבי-פיתוח בסביבת פיתוח אוהדת שמעודדת אותם ונותנת להם את כל ההרשאות שהם צריכים כדי לרוץ. ואז שהתוכנה עוברת ללקוח שה-IT שלו החליט שכל תוכנה שהוא לא אישר לא מקבלת שום גישה לרשת של החברה - הכל נופל כמו מגדל קלפים.

בוא נגיד ותוכנת המחשבון שלנו היא למעשה תוכנת שרת-לקוח שחייבת גישה לרשת או תוכנת דו"חות שחייבת גישה למדפסות או תוכנת עיבוד תמונה שחייבת גישה למסך. נלך על הדוגמה הראשונה. האסמבלי שלנו חייבת כגישה מינימלית גישה לרשת. בלי זה, אין לתוכנה מה לעשות.

נפתח את קובץ ה-AssemblyInfo.cs שלנו ושם אנו יכולים לבקש לאסמבלי גישות מינימליות ואופציונליות וגם לבקש שלאסמבלי שלנו יסרבו גישה. בואו נגדיר את גישת הרשת כדרישה מינימלית:

// AssemblyInfo.cs
using System.Security;
using System.Security.Permissions;

//...
[assembly: PermissionSet(
    SecurityAction.RequestMinimum,
    Name="LocalIntranet")]
//...

ובכך דרשנו כגישה מינימלית לאפליקציה שלנו גישה לאינטרה-נט של הארגון. עכשיו בואו נציג מקרה הפוך, אנחנו לא כותבים תוכנת שרת-לקוח, אלא תוכנת ציור פרחים. התוכנה יודעת לצייר פרחים. האסמבלי שלה לא צריכה גישה לרשת המקומית של הארגון, ולכן נרצה לסרב גישה לאותה גישה לאסמבלי שלנו.

// AssemblyInfo.cs
using System.Security;
using System.Security.Permissions;

//...
[assembly: PermissionSet(
    SecurityAction.RequestRefused,
    Name="LocalIntranet")]
//...

בנושא הגדרת אבטחה לאסמבלי אפשר לקחת שתי גישות:

  • להגדיר מראש אילו הרשאות האסמבלי תצטרך ולהגדיר לאילו הרשאות לסרב.
  • לא להגדיר מראש אילו הרשאות האסמבלי תצטרך, אבל להיות מוכנים לאלף ואחת SecurityExceptions שיקפצו לנו. והכוונה לא רק בזמן הפיתוח, אלא גם ובעיקר אצל הלקוח עצמו. מעניין מה הלקוח יחשוב שתוכנת השרת-לקוח שלנו נופלת בזמן שהיא מנסה להתחבר לרשת, או תוכנת דו"חות בזמן ששולחים אותה למדפסת.

 

ג. מהן Strong named assemblies וכיצד הופכים אסמבלי רגילה ל-Strong named

הזכרנו בחלק א' שכל מניפסט מכיל את שם האסמבלי, גירסת האסמבלי, התרבות אליה היא קשורה והמפתח שלה. אלו הם ארבעת הפרטים המזהים של האסמבלי. (ישנו חלק חמישי שנקרא Digital signature, ולא נעסוק בו)

שם האמסבלי נקבע בקובץ ה-AssemblyInfo.cs ואם לא קבענו אותו הוא יהיה ריק.

// AssemblyInfo.cs
[assembly: AssemblyTitle("Justin_Calc")]
// or for an empty name:
[assembly: AssemblyTitle("")]

גירסת האמסבלי רשומה בקובץ ה-AssemblyInfo.cs ואם לא קבענו אותו הוא יהיה ספרור רץ כך שכל בנייה שונה של האמסבלי תקבל מספר גירסה שונה.

// AssemblyInfo.cs
[assembly: AssemblyVersion("1.2.3.100")]

// or the default value that gives each build a unique version:
[assembly: AssemblyVersion("1.0.*")]

תרבות האסמבלי גם היא רשומה בקובץ ה-AssemblyInfo.cs. בתרבות הכוונה היא שלאסמבלי כלשהי יכולות להיות גרסאות רבות וכאשר אסמבלי אחרת רוצה לטעון את האסמבלי הראשונה היא יכולה לטעון גירסה שהיא תלויית תרבות. למשל, אם נרצה נוכל לטעון אסמבלי של מחשבון שיודעת לטפל ספציפית במספרים צרפתיים (במקום נקודה עשרונית יש פסיק ובמקום פסיקים יש נקודה) ונוכל להכין אסמבלי של מחשבון שיודע לטפל במספרים כפי שאנו מכירים אותם מהתרבות המטרית. אם לא נגדיר אסמבלי, היא תהיה ה-Invarient culture, כלומר בלתי תלויה בתרבות כלשהי.

// AssemblyInfo.cs
[assembly: AssemblyCulture("He-Il")]        

// or for the invarient culture:
[assembly: AssemblyCulture("")]

המפתח הוא למעשה החלק שהופך את האמסבלי ל-Strong name assembly. מדובר למעשה בקובץ עם סיומת snk שאנו נפנה אליו מתוך ה-assembly. הקובץ הזה יכיל מפתח ציבורי ומפתח פרטי בשביל זיהוי האמסבלי ע"י אסבמליס אחרות. נפתח את ה-Visual studio 2003 command prompert (מסך שחור דמוי DOS) ונכתוב:

sn.exe -k c:\myTestKeyFile.snk

מה שנקבל הוא שבכונן C יווצר קובץ בשם myTestKeyFile.snk והוא מכיל זוג מפתחות לאפליקציה שלנו: אחד ציבורי ואחד פרטי. נעתיק את הקובץ מכונן C לתוך תיקיית הפרוייקט שלנו, לאותה תיקייה בה יושב קובץ ה-AssemblyInfo.cs שלנו. נערוך את ה-AssemblyInfo.cs כך שהוא יצביע על המפתח:

[assembly:AssemblyKeyFileAttribute("myTestKeyFile.snk")]

ארבעת הפרטים הללו: שם האסמבלי, גירסת האסמבלי, תרבות האסמבלי והמפתח שלה הופכים אותה ל-Strong name. (צריך להדגיש שחובה גם לבצע Build לאסמבלי לפני שהיא באמת הופכת לאחת כזו).

אז למה זה טוב? במילה אחת (או שלוש), זיהוי אחד ויחיד. יצרנו עכשיו אסמבלי שלה ולה בלבד יש את התכונות הללו. זיהוי וודאי.

קיימת תיקייה שנקראת Global Assembly Cache (או בקיצור: GAC). הסבר מקיף על התקייה הזאת היא מחוץ לתחום המאמר הזה, אבל נסקור בהקשרנו מה חשיבותה. בתיקייה זו ניתן לפרוס\להתקין Strong-named assemblies. ברגע שנתנו את ארבעת התכונות שהזכרנו לעיל (וליתר הדיוק, ברגע שנתנו לאסמבלי קובץ מפתח) היא נחשבת Strong named assembly. למה צריך תיקייה מיוחדת? סיבה ראשונה היא שהפריימוורק דבר ראשון ניגשת לשם לחפש אסמבליס מה שמקל מאוד על פריסת מערכות (נרחיב על כך בהמשך), סיבה שנייה היא כדי לנהל גרסאות.

אם היום נבנה את גירסה 1.0 של המנוע של המחשבון שלנו, ומחר נבנה את גירסה 1.1, מבחינת מערכת ההפעלה (עליה יושבים הקבצים) אין ביניהם שום הבדל. שניהם נקראים Justin_Calc.dll. בתיקייה מסויימת יכול לשבת רק עותק אחד של אותה אסמבלי. לעומת זאת, ב-GAC יכולות לשבת מספר גרסאות של אותה אסמבלי.

בניתי אפליקציית web שעובדת על גירסה 1.0 של מנוע המחשבון ומאחר והוא כזה טוב קיבלתי ישר הצעות לחשוף את המנוע בתור Webservice לעולם מחברות שמוכנות לשלם. אבל צריך לשנות כמה מתודות, כמה מהחתימות הקיימות של המתודות, להוסיף כמה מתודות, קיצר - שינוי טוטאלי באסמבלי. נשנה את הגירסהשל המנוע שלנו ל-2.0. ב-GAC שלנו יכולות לשבת גם גירסה 1.0 וגם גירסה 2.0, וכל אפליקציה יודעת עם איזו גירסה היא אמורה לעבוד. האפליקציית ASP.net שלי יודעת לעבוד עם גירסה 1.0 וה-Webservice יודע לעבוד עם גירסה 2.0.

הניהול המאוד פשוט והגיוני הזה של גירסאות שונות של אותה אסמבלי שעובדות כולן מאותו ספרייה מנע המון המון בעיות שהיוא נפוצות בטכנולוגיות קודמות.

ד. איפה וכיצד מחפשת האסמבלי את האסמבליס בהן היא תלויה.

ברגע שהגדרנו שאסמבלי תלויה באסמבליס אחרות, נפתחת לנו בעיה חדשה לחלוטין: אם פתחנו אפליקיית דוט נט למשל עם סיומת EXE שראינו שהיא אסמבלי, איפה היא תחפש את ה-DLLים שהיא תלויה בהם? (כנ"ל כמובן יהיה תקף על אפליקציןת ASP.net ו-Webserviceים)

  1. דבר ראשון שהפריימוורק עושה זה לברר את הפרטים של האמסבלי אותה היא מחפשת. שם האמסבלי, הגירסה של האסמבלי, התרבות שלה והמפתח הציבורי שלה (כפי שהוא מופיע בקובץ המפתח שהוספנו לאסמבלי שלנו). אפשר לראות דוגמה לקישור ל-System.Drawing מתוך אפליקציית ה-WinCalc שלנו כפי שהוא נראה בReflector:
    Assembly9.gif
  2. הפריימוורק תחפש בקבצי קונפיגיורציה למיניהם הוראות מיוחדות. קבצי קונפיגיורציה כאלו יכולים לבוא בסמוך לאסמבלי שנטענת לזכרון, יכולים להיות ברמת המכונה וניתן גם שהם יהיו ברמת הארגון. בקבצים כאלו נקבעת מדיניות בנושא שימוש באסמבליס מסויימות, אך אינם הכרחיים לעבודה עימן ולכן לא נסקור אותם במאמר זה.
  3. הפריימוורק תבדוק אם האסמבלי שהיא מחפשת כבר נטענה לאחרונה לזכרון ואם כן, בזה מסתיים החיפוש.
  4. אם הפריימוורק מחפשת אסמבלי שהיא Strong name היא עכשיו תחפש בספריית ה-GAC.
  5. אם הפריימוורק לא מצאה עד עכשיו את האסמבלי היא תתחיל "לחפור" בתוך התיקייה של האסמבלי שרוצים לטעון לזכרון. אם לאפליקציה שלנו קוראים WinCalc (שיושבת ישירות על כונן C) והאסמבלי שאנו מחפשים היא בעלת השם Justin_Calc בתרבות He-IL אלו יהיה הנתיבים בהם תחפש הפיימוורק: (לפי הסדר)

C:\WinCalc\Justin_Calc.dll
C:\WinCalc\Justin_Calc\Justin_Calc.dll
C:\WinCalc\Justin_Calc.exe
C:\WinCalc\Justin_Calc\Justin_Calc.exe
C:\WinCalc\He-IL\Justin_Calc.dll
C:\WinCalc\He-IL\Justin_Calc\Justin_Calc.dll
C:\WinCalc\He-IL\Justin_Calc.exe
C:\WinCalc\He-IL\Justin_Calc\Justin_Calc.exe

ה. יתרונות ה-Strong name לאסמבליס

  1. יחודיות שם האסמבלי בעזרת המפתח - אי-אפשר ליצור בטעות שתי אסמבליס עם מפתח פרטי וציבורי זהים. באמצעות היחודיות הזו אפשר לבצע זיהוי וודאי שהאסמבלי אליה קשרנו את האסמבלי שלנו היא אכן האסמבלי שאנו צריכים.
  2. פריסה ב-GAC - אסמבלי שאינה Strong-name לא ניתן לפרוס ב-GAC. פריסה ב-GAC מבטיחה שללא חשיבות היכן נתקין על אותה מכונה את האפליקציה שלנו היא תמיד תמצא את האסמבליס בהן היא משתמשת.  אנחנו לא צריכים להתחיל להתעסק עם איפה פרסנו את האסמבליס שלנו, היות וברגע שפרסנו אותן ל-GAC הפריימוורק תמיד תמצא אותן.
  3. ניהול גרסאות נכון בפריסת מערכות -  כאשר יש לנו גירסה אחת ויחידהשל אסמבלי אליה אנו רוצים ליצור קישור אז הכל בסדר. אבל ברגע שיש לנו שתי גרסאות (או מאות גרסאות!) כבר אי-אפשר סתם להעתיק אותה לתוך תיקיית הפרוייקט. אנחנו נתחיל להסתבך עם "רגע, איזה גרסה יש לנו כרגע מותקנת שם?" ו-"לעזאזל, אני עובד עם הגירסה הלא נכונה בזמן פיתוח" ועוד נענה ללקוח "זה בסדר, זה בסדר, הכל פועל פשוט יש לך גירסה לא נכונה של המנוע הזה והזה".
  4. התייחסות להבדלי גירסאות - אם  נבחר אמסבלי לאסמבלי אחרת, נוכל להחליף את האסמבלי שמחברים בטעות בגירסה אחרת שלה ע"י העתקת הגירסה הלא-נכונה לתוך ספריית האפליקציה. לעומת זאת, כאשר אנו עובדים עם Strong name האפליקציה שמחפשת את האסמבליס הקושרות אליה מחפשת גירסה ספציפית. באסמבליס שהן לא Strong name אין חשיבות מבחינת הקישוריות בין אסמבליס לאיזה גירסה קבענו.
מבחינה תפיסתית, כאשר אנו רוצים ליצור אסמבלי שהיא משותפת בין שתיים (או יותר) אפליקציות שלנו ו\או עשויה לצאת במספר גרסאות, תמיד לפני פריסת המערכת ניצור אותה כ-Strong name ובכך נמנע מאין ספור מרעין-בישין שתמיד ניתקל בהם אם לא נעשה כך.

 

לסיכום

דיברנו על מה הן אסמבליס, מה הן מכילות, מה היתרונות של עבודה בצורה של אסמבליס, כיצד אסמבלי מתארת את עצמה, כיצד ניתן להגדיר הגדרות אבטחה ברמת האסמבלי, כיצד יוצרים קישוריות בין אסמבליס ומה הבעיות באותן קישוריות, היכן ניתן לפרוס אסמבליס, מהי הדרך הטובה ביותר לפרוס אסמבליס ומתי להשתמש בה והראנו את הפתרון לבעיית הקישוריות, בעיית הגירסאות ובעיית מיקום הפריסה בצורה של Strong named assemblies.

 

בהצלחה לכולכם,

ג'סטין-יוסף אנג'ל 

 

שינויים:
1. 15.11.05 -תוקנה ההתייחסות בדוגמה של המחשבון מ-Refrence מ-System.Windows ל-Refrence ל-System.Windows.Forms. תודה לאורן ואריק שציינו את זה.

11/12/2005 10:57:23 PM (Jerusalem Standard Time, UTC+02:00)
המאמרים שלך עוזרים לי הרבה, כבר קראתי הרבה מהם.
תמשיך ככה .
:)
shahar
9/3/2006 1:02:57 PM (Jerusalem Standard Time, UTC+02:00)
המאמרים שלך מעולים,

ועכשיו רעיון למאמר נוסף:

איך הופכים dll נתון שנוצר בשפת c++ לרכיב אסמבלי בשביל שאוכל ליבא אותו מ-C#?

דחוף
תודה
11/27/2006 3:03:37 AM (Jerusalem Standard Time, UTC+02:00)
שלום וברכה
דבר ראשון קראתי הרבה מאמרים שלך, הם מאוד מקיפים והם באמת עוזרים המון..
לא ידעתי איפה לשים את השאלה הזו אז שמתי איפה שהיה נראה לי הכי קרוב.
אז ככה, מדובר בניהול נכון של מרחבי שמות (default namespase[במאפיינים של כל פרוייקט]), למדתי שטוב ועדיף כשעובדים עם שכבות לתת בnamespase שם החברה נקודה שם השכבה נקודה שם הפרוייקט (לדוגמה ness.DAL.booksDataאו ness.DT.bookDAL) אם ת'יכול להבהיר לי את העניין לעומק כמו שאתה יודע לעשות בדר"כ אני אשמח מאוד כי אני מנסה להתמחות בעניין וזה לא כ"כ מובהר לי.
תודתי נתונה לך מראש
שמעון
Name
E-mail
Home page

Comment (HTML not allowed)  

Enter the code shown (prevents robots):