בעיה עם Assembly Redirection (זה שנמצא ב App.config)

מiטקה

New member
בעיה עם Assembly Redirection (זה שנמצא ב App.config)

שלום חברים,

אני כותב תכנית C# שה User Interface שלה הוא ב PowerShell (יש שם את הפקודה Out-GridView וזה מאוד נוח כשצריך להציג הרבה מידע ולפלטר אותו)
התכנית עצמה כתובה בC# ורק יצירת המופעים של ה Class-ים והקריאה לפונקציות שלהם נעשית מתוך PowerShell.
כלומר, ב Main אני מפעיל Proccess של PowerShell שהוא קורא לקוד ה C# מבחוץ.

הבעיה היא כזאת.
תכנית ה C# משתמשת בכמה Assemblies נקרא להם Ass1.dll ו Ass2.dll..
ל Ass2.dll יש 2 גירסאות v1,v2.
Ass1.dll הוא Dependent ב Ass2.dll והוא דורש את גירסה v1 ומעלה.
מכיוון שהתכנית עצמה צריכה את גירסת v2 של ה Assemblies, לכן ב References יש את Ass1.dll וכן את Ass2.dll v2.
מתוך C# הכל עובד טוב כי אמנם Ass1.dll קורא ל Ass2.dll v1 אבל מכיוון שב App.config מוגדר Redirection שבו Ass1.dll v1-v2 -> v2 לכן התכנית עובדת.

הבעיה היא מתוך PoweShell.
כאשר אני מפעיל את ה PowerShell אני טוען לתוכו את כל ה Assemblies הדרושים (הם הרי נמצאים בתיקיית ה bin כי הם קומפלו מתוך הC#)
אבל כאשר אני מנסה לקרוא לפונקציה שנמצאת ב Ass1.dll שכזכור משתמש ב Ass2.dll התכנית נופלת עם הודעת שגיאה ש Ass2.dll v1 לא נטען לתוך התכנית.
העניין הוא ש App.config של C# לא מוגדר עבור PowerShell ולכן הוא לא יודע להפנות אוטומטית ל Ass2.dll v2.

מישהו נתקל בבעיה ויכול להביא תובנות?

הפתרון שאני מעוניין:
הגדרת Redirectionשבו Ass1.dll v1-v2 -> v2 וטעינה שלו לתוך PowerShell תוך כדי ריצה.
האם זה אפשרי?
גם קוד ב C# הוא טוב, המרה שלו ל PowerShell לא אמורה להיות מסובכת בשבילי.

פתרונות לא טובים:
1. הורדה ידנית של Ass2.dll v2 וצירוף שלו לתוך C# ואחר כך טעינה שלו מתוך PowerShell.
הבעיה: C# מזהה ש יש לו 2 גירסאות של אותו Assembly ולכן מביא רק את החדש יותר.
2. העתקה של הקבצים ב PostBuildEvent.
הבעיה: התכנית אמורה לעבוד כ ClickOnce עבור הרבה משתמשים אבל ה Publish של ה ClickOnce לא יודע לזהות את ה PostBuildEvent.
3. העתקה ידנית של ה Assemblies.
הבעיה: ידני זה לא טוב וגם זה בעייתי עם ה ClickOnce.
4. הוספת Event OnAssemblyResolve שידע להחזיר את ה Assembly המתאים.
הבעיה גורם ל StackOverflow (לא יודע למה).
5. עדכון ה App.config של PowerShell עוד בשלב של ריצת ה C# ורק אחר כך טעינה של PowerShell.
הבעיה: פתרון לא נקי וגם דורש ריצה כ Admin (שכמובן אין לי במחשבים של כל המשתמשים).
6. עוד כלמיני נסיונות


תודה לכולם .
 

pelegk11

New member
צריך לראות את הפרוייקט כדי להבין

יש לך אפשרות להעלות אותו כדי לבצע מספר בדיקות (תוריד קוד שאתה לא רוצה לחשוף)
 

מiטקה

New member
להעלות את הפרוייקט קצת בעייתי אבל אני יכול לביא לך את המקרה

כתבתי class ובתוכו פונקציה שמקבלת נתונים מ Azure table ומבצעת כמה מוניפולציות עליהם.
ה class מסתמך על כמה Assemblies ובתוכם על Microsoft.Data.OData וכל על Microsoft.Data.Edm. שניהם נמצאים אצלי בגירסה 5.6.3.
העניין הוא ש OData מסתמך על Edm בגירסה 5.6.2 ומעלה מה שגורם לבעיה שתיארתי.
 
ניסית לעבוד עם ILMerge?

אתה יכול למזג שם מספר אסמבליז לאסמבלי אחד (כאילו לכרוך אותם) ואז כל ה dependencies זמינים לך מיידית.
זה פתר לי (בזמנו) בעיית versioning מסויימת.
 

מiטקה

New member
זה בעייתי כי אני מסתמך על nuget ואני מעוניין לקבל עדכונים

 

MyVirtualSelf

New member
רעיון

נשמע שהבעיה שלך היא להריץ מתוך ה-PowerShell עם קונפיגורציה שאתה בוחר, ושה-Assembly Redirect הוא רק תסמין של הבעיה.
הייתי מנסה לשנות את הקוד כך שיצור AppDomain חדש אשר משתמש בקובץ ה-Config שאתה מעוניין בו, ומריץ את הקוד בתוך ה-AppDomain הזה.
 

מiטקה

New member
לא הלך משהו

בלאגן שלם
הייתי צריך להגדיר את המחלקה ואת כל המשתנים שלה כ serializable או marshalByRefObject
לגבי MarshalByRefObject זה רק כשאני לא יורש ממישהו אחר כי אין ירושה מרובה.
לגבי serializable זה לא עבד טוב כי האובייקט שאני מקבל מAzureTable צריך לרשת מ TableEntity שמכיל בתוכו Event-ים שאי אפשר להגדיר כ Serializable.
אז מה שהייתי צריך לעשות זה ליצור class חדש עם האובייקטים שאני רוצה, להגדיר אותו כ serializable ולהמיר את ה entity שלי לclass החדש.
אחרי שעשיתי את כל זה זה עבד יפה מתוך AppDomain שונה כשהייתי ב C# אבל ברגע שעברתי ל PowerShell זה החזיר null.
 
למעלה