ฉันต้องทำหลายครั้งและค้นคว้าวิธีแก้ปัญหาต่างๆมากมาย
วิธีแก้ปัญหาที่ฉันพบในความหรูหราและง่ายที่สุดสามารถนำไปใช้ได้เช่นนี้
1. สร้างโปรเจ็กต์ที่คุณสามารถสร้างอินเทอร์เฟซง่ายๆ
อินเทอร์เฟซจะมีลายเซ็นของสมาชิกที่คุณต้องการโทรหา
public interface IExampleProxy
{
string HelloWorld( string name );
}
สิ่งสำคัญคือต้องทำให้โครงการนี้สะอาดและเป็นประโยชน์ เป็นโครงการที่ทั้งสองAppDomainสามารถอ้างอิงได้และจะช่วยให้เราไม่สามารถอ้างอิงถึงสิ่งที่Assemblyเราต้องการโหลดในโดเมนแยกจากแอสเซมบลีไคลเอ็นต์ของเรา
2. AppDomainตอนนี้สร้างโครงการที่มีรหัสที่คุณต้องการที่จะโหลดในแยก
โปรเจ็กต์นี้เช่นเดียวกับไคลเอนต์พร็อกจะอ้างอิงพร็อกซีพร็อกและคุณจะใช้อินเทอร์เฟซ
public interface Example : MarshalByRefObject, IExampleProxy
{
public string HelloWorld( string name )
{
return $"Hello '{ name }'";
}
}
3. ถัดไปในโปรเจ็กต์ไคลเอนต์โหลดโค้ดในอีกAppDomainอัน
ตอนนี้เราสร้างไฟล์AppDomain. สามารถระบุตำแหน่งฐานสำหรับการอ้างอิงการประกอบ การตรวจสอบจะตรวจสอบแอสเซมบลีที่ขึ้นต่อกันใน GAC และในไดเร็กทอรีปัจจุบันและAppDomainฐานข้อมูล
// set up domain and create
AppDomainSetup domaininfo = new AppDomainSetup
{
ApplicationBase = System.Environment.CurrentDirectory
};
Evidence adevidence = AppDomain.CurrentDomain.Evidence;
AppDomain exampleDomain = AppDomain.CreateDomain("Example", adevidence, domaininfo);
// assembly ant data names
var assemblyName = "<AssemblyName>, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null|<keyIfSigned>";
var exampleTypeName = "Example";
// Optional - get a reflection only assembly type reference
var @type = Assembly.ReflectionOnlyLoad( assemblyName ).GetType( exampleTypeName );
// create a instance of the `Example` and assign to proxy type variable
IExampleProxy proxy= ( IExampleProxy )exampleDomain.CreateInstanceAndUnwrap( assemblyName, exampleTypeName );
// Optional - if you got a type ref
IExampleProxy proxy= ( IExampleProxy )exampleDomain.CreateInstanceAndUnwrap( @type.Assembly.Name, @type.Name );
// call any members you wish
var stringFromOtherAd = proxy.HelloWorld( "Tommy" );
// unload the `AppDomain`
AppDomain.Unload( exampleDomain );
หากคุณต้องการมีหลายวิธีในการโหลดชุดประกอบ คุณสามารถใช้วิธีอื่นกับโซลูชันนี้ หากคุณมีชื่อแอสเซมบลีที่มีคุณสมบัติเหมาะสมฉันต้องการใช้CreateInstanceAndUnwrapเนื่องจากมันโหลดไบต์แอสเซมบลีจากนั้นสร้างอินสแตนซ์ประเภทของคุณให้คุณและส่งคืนค่าobjectที่คุณสามารถส่งไปยังประเภทพร็อกซีของคุณอย่างง่ายหรือหากคุณไม่ได้พิมพ์เป็นรหัสที่พิมพ์มากคุณสามารถทำได้ ใช้รันไทม์ภาษาแบบไดนามิกและกำหนดอ็อบเจ็กต์ที่ส่งคืนให้กับdynamicตัวแปรที่พิมพ์แล้วเพียงแค่เรียกสมาชิกจากนั้นโดยตรง
ที่นั่นคุณมี
สิ่งนี้ช่วยให้สามารถโหลดแอสเซมบลีที่ proj ไคลเอนต์ของคุณไม่มีการอ้างอิงในการแยกAppDomainและเรียกสมาชิกจากไคลเอนต์
ในการทดสอบฉันต้องการใช้หน้าต่าง Modules ใน Visual Studio จะแสดงโดเมนแอสเซมบลีไคลเอ็นต์ของคุณและโมดูลทั้งหมดที่โหลดในโดเมนนั้นรวมถึงโดเมนแอพใหม่ของคุณและแอสเซมบลีหรือโมดูลใดบ้างที่โหลดในโดเมนนั้น
กุญแจสำคัญคือการตรวจสอบให้แน่ใจว่ารหัสของคุณได้มาMarshalByRefObjectหรือสามารถต่ออนุกรมกันได้
`MarshalByRefObject จะอนุญาตให้คุณกำหนดค่าอายุการใช้งานของโดเมนในตัวอย่างเช่นคุณต้องการให้โดเมนทำลายหากไม่มีการเรียกใช้พร็อกซีใน 20 นาที
ฉันหวังว่านี่จะช่วยได้.