ฉันต้องทำหลายครั้งและค้นคว้าวิธีแก้ปัญหาต่างๆมากมาย
วิธีแก้ปัญหาที่ฉันพบในความหรูหราและง่ายที่สุดสามารถนำไปใช้ได้เช่นนี้
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 นาที
ฉันหวังว่านี่จะช่วยได้.