2010-05-31 17 views
3

AppDomains에 대해 몇 시간 씩 읽은 적이 있지만 제대로 작동하는지 확신 할 수 없습니다. 나는 두 개의 클래스, 응용 프로그램 도메인 # 1의 일반적인 푸 <T>이있는 경우.NET AppDomains가이 작업을 수행 할 수 있습니까?

는, 바의 AppDomain에서 # 2 :

응용 프로그램 도메인 # 1은 응용 프로그램입니다. App Domain # 2는 플러그인과 비슷하며 동적으로로드 및 언로드 할 수 있습니다.

AppDomain # 2는 Foo <Bar>을 만들고 사용하려고합니다. Foo <T>은 내부적으로 AppDomain # 1에서 많은 클래스를 사용합니다.

리플렉션에서 foo 개체를 사용하여 AppDomain # 2를 사용하고 싶지 않습니다. Foo <Bar> foo를 사용하고 싶습니다. 모든 정적 입력과 컴파일 속도가 함께 사용됩니다. Foo <T>을 포함하는 AppDomain # 1이 언로드되지 않는다는 것을 고려하여이 작업을 수행 할 수 있습니까?

그렇다면 Foo <Bar>을 사용할 때 리모 세션이 발생합니까?

AppDomain # 2를 언로드하면 Foo <Bar> 유형이 삭제됩니까?

편집 모두 내 < >을 삭제했습니다. 수동으로 다시 추가했습니다.

답변

6

질문에 유형 및 개체가 혼합되어있어 대답하기 어렵습니다. AD의 코드는 다른 AD에서도 사용되는 유형을 사용하는 데 문제가 없으며 단순히 어셈블리를로드합니다. 하지만 광고에는 가비지 수집 힙이 있으므로 다른 AD에있는 객체를 직접 참조 할 수는 없습니다. 광고 경계를 넘어 직렬화해야합니다. 예, IpcChannel을 통한 원격 조작은 그렇게 할 것입니다.

+0

IpcChannel은 필요하지 않습니다. appdomain.CreateInstance를 사용하여이 작업을 수행 할 수 있습니다. 문제의 클래스가 직렬화 가능하거나 marshalobjbyref이면, 원격 채널을 구성하지 않고도 원하는 것을 얻을 수 있습니다. .NET 런타임은 동일한 컴퓨터에 있기 때문에 높은 효율성으로 두 앱 도메인간에 원격 작업을 수행하는 방법을 알기에 충분히 똑똑합니다. –

+0

좋아, 이해해 주시면 Foo 을 만들 수 있습니다. AppDomain # 2의 인스턴스는 아무런 문제가없고 정상적으로 사용합니다. 리모컨이 필요하지 않습니다. Foo 을 포함하는 어셈블리에로드하면됩니다. AppDomain # 1은 관리되지 않는 리소스를 보유하고 관리하는 몇 개의 정적 인 수명이 긴 싱글 톤을 포함하는 어셈블리를 분리하여 하나의 복사본 만 포함되도록합니다. Foo를 가질 필요가 없습니다 여기에. 여기서 AppDomain # 2의 Foo 은 AppDomain # 1에서 이러한 개체를 사용하는데 일종의 원격 처리가 필요합니다. AppDomains에서 정적 메서드 호출을 수행하는 몇 가지 방법은 무엇입니까? – Eloff

+0

@Vagaus가 대답을 갖고있는 것처럼 보입니다. AppDomain # 1 하위 클래스 인 MarshalByRefObject에 개체가 있고 AppDomain # 2에서 오랫동안 살았던 싱글 톤의 프록시로 끝납니다. AppDomain # 2에서 행복하게 사용할 수 있습니다. 투명하게 마샬링합니다. AppDomain 경계에서 메서드 인수와 반환 값 – Eloff

1

응용 프로그램 도메인 간 개체에 액세스하려는 경우이 개체는 MarshalByRefObject에서 상속해야합니다. 그런 시나리오에서는 실제 객체에 대한 프록시가 생깁니다. 이렇게하면 응용 프로그램 도메인을 언로드하는 것이 안전합니다 (프록시를 통해 호출하려고하면 예외가 발생합니다).

내가 무엇을 달성하려고하는 것은 같은 것입니다 추측 : 당신의 유형 (가능성이있는) 당신은 아마 (일반적인 어셈블리) 인터페이스를 정의 할 것이다 다른 어셈블리에 정의되어있는 경우

using System; 
using System.Reflection; 

namespace TestAppDomain 
{ 
class Program 
{ 
    static void Main(string[] args) 
    { 
     AppDomain pluginsAppDomain = AppDomain.CreateDomain("Plugins"); 

     Foo foo = new Foo(); 
     pluginsAppDomain.SetData("Foo", foo); 

     Bar bar= (Bar) pluginsAppDomain.CreateInstanceAndUnwrap(Assembly.GetEntryAssembly().FullName, typeof (Bar).FullName); 
     bar.UseIt(); 

     AppDomain.Unload(pluginsAppDomain); 
     foo.SaySomething(); 
    } 
} 

class Bar : MarshalByRefObject 
{ 
    public void UseIt() 
    { 
     Console.WriteLine("Current AppDomain: {0}", AppDomain.CurrentDomain.FriendlyName); 
     Foo foo = (Foo) AppDomain.CurrentDomain.GetData("Foo"); 
     foo.SaySomething(); 
    } 
} 

class Foo : MarshalByRefObject 
{ 
    public void SaySomething() 
    { 
     Console.WriteLine("Something from AppDomain: {0}", AppDomain.CurrentDomain.FriendlyName); 
    } 
} 
} 

가 형태가이 인터페이스를 구현하도록 (듯이)합니다.

희망이 도움이됩니다.

관련 문제