이 작업을 여러 번해야했고 다양한 솔루션을 연구했습니다.
내가 가장 우아하고 달성하기 쉬운 솔루션은 그렇게 구현할 수 있습니다.
1. 간단한 인터페이스를 만들 수있는 프로젝트 만들기
인터페이스에는 호출하려는 모든 구성원의 서명이 포함됩니다.
public interface IExampleProxy
{
string HelloWorld( string name );
}
이 프로젝트를 깨끗하고 가볍게 유지하는 것이 중요합니다. 둘 다 AppDomain
참조 할 수 있는 프로젝트이며 Assembly
클라이언트 어셈블리에서 별도의 도메인에로드하려는 항목을 참조하지 않도록합니다.
2. 이제로드하려는 코드가있는 프로젝트를 개별적으로 AppDomain
만듭니다.
클라이언트 proj와 마찬가지로이 프로젝트는 프록시 proj를 참조하고 인터페이스를 구현합니다.
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
형식화 된 변수에 할당 한 다음 해당 변수에 대한 멤버를 직접 호출합니다.
거기에 있습니다.
이를 통해 클라이언트 프로젝트가 별도의 참조가없는 어셈블리를로드 할 수 있습니다. AppDomain
멤버를 호출 할 수 있습니다.
테스트하기 위해 Visual Studio의 모듈 창을 사용하고 싶습니다. 클라이언트 어셈블리 도메인과 해당 도메인에로드 된 모든 모듈과 새 앱 도메인, 해당 도메인에로드 된 어셈블리 또는 모듈이 표시됩니다.
핵심은 코드가 다음 중 하나를 파생하는지 확인하는 것입니다. MarshalByRefObject
되거나 직렬화 입니다.
`MarshalByRefObject를 사용하면 도메인의 수명을 구성 할 수 있습니다. 예를 들어 프록시가 20 분 내에 호출되지 않은 경우 도메인이 파괴되도록 할 수 있습니다.
이게 도움이 되길 바란다.