Application Domain #2 - AppDomain 사용

2021. 4. 19. 14:32

1. Create Application Domain

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Create new AppDomain");
        AppDomain domain = AppDomain.CreateDomain("MyDomain");

        Console.WriteLine("Host domain  : " + AppDomain.CurrentDomain.FriendlyName);
        Console.WriteLine("Child domain : " + domain.FriendlyName);

        Console.WriteLine("\nPlease Endter Key...\n");
        Console.ReadKey();
    }
}

 

 

2. Unload Application Domain

class Program
{
    static void Main(string[] args)
    {
        Console.WriteLine("Creating new AppDomain.");
        AppDomain domain = AppDomain.CreateDomain("MyDomain", null);

        Console.WriteLine("Host domain: " + AppDomain.CurrentDomain.FriendlyName);
        Console.WriteLine("child domain: " + domain.FriendlyName);

        try
        {
            AppDomain.Unload(domain);
            Console.WriteLine();
            Console.WriteLine("Host domain: " + AppDomain.CurrentDomain.FriendlyName);

            // The following statement creates an exception because the domain no longer exists.
            Console.WriteLine("child domain: " + domain.FriendlyName); //AppDomainUnloadedException

            Console.WriteLine("\nPlease Endter Key...\n");
            Console.ReadKey();

        }
        catch(AppDomainUnloadedException ex)
        {            
            Console.WriteLine(ex.GetType().FullName);
            Console.WriteLine("The appdomain MyDomain does not exist.");

            Console.WriteLine("\nPlease Endter Key...\n");
            Console.ReadKey();
        }
    }
}
  • 언로드 프로세스 중에는 새 스레드가 애플리케이션 도메인에 액세스할 수 없음
  • 어셈블리가 도메인 중립적인 경우, 해당 어셈블리의 데이터는 전체 프로세스가 종료될 때까지 메모리에 잔류
  • 따라서, 도메인에 중립적인 어셈블리를 언로드하려면 전체 프로세스를 종료하는 것이 유일한 메커니즘

 

 

 

3. Setup Application Domain

class Program
{
    static void Main(string[] args)
    {
        // Create application domain setup information.
        AppDomainSetup domaininfo = new AppDomainSetup();
        domaininfo.ApplicationBase = System.IO.Directory.GetCurrentDirectory();

        // Create the application domain.
        AppDomain domain = AppDomain.CreateDomain("MyDomain", null, domaininfo);

        // Write application domain information to the console.
        Console.WriteLine("Host domain: " + AppDomain.CurrentDomain.FriendlyName);
        Console.WriteLine("child domain: " + domain.FriendlyName);
        Console.WriteLine("Application base is: " + domain.SetupInformation.ApplicationBase);

        // Unload the application domain.
        AppDomain.Unload(domain);

        Console.WriteLine("\nPlease Endter Key...\n");
        Console.ReadKey();
    }
}
  • AppDomainSetup Class를 사용하여 새 AppDomain 구성 정보를 CRL에 제공할 수 있다.
  • ApplicationBase 속성 : 사용자 고유의 AppDomain을 만들 때 가장 중요한 속성
    • root directory 지정
    • 런타임에서 형식 요청을 충족해야 하는 경우, ApplicationBase 속성에 지정된 Directory에서 해당 형식을 포함하는 어셈블리는 찾음

 

 

4. Load Assembly into Application Domain

class Program
{
    static void Main(string[] args)
    {
        // Use the file name to load the assembly into the current
        // application domain.
        System.Reflection.Assembly a = System.Reflection.Assembly.Load("ClassLibrary1");
        // Get the type to use.
        // example      Namespace
        // Class1       Class
        // example_1    Dll file name
        
        Type myType = a.GetType("ClassLib.MyClass");
        
        // Get the method to call.
        System.Reflection.MethodInfo myMethod = myType.GetMethod("MethodA");
        // Create an instance.
        object obj = Activator.CreateInstance(myType);
        // Execute the method.
        object obj2 = myMethod.Invoke(obj, null);
    }
}
namespace ClassLib
{
    public class MyClass
    {
        public string Name { get; set; }

        public string MethodA()
        {
            return "Hell Assembly";
        }
    }
}
  • AppDomain에 Assembly를 Load하는 방법은 다양함
    1. "System.Reflection.Assembly" 클래스의 static "Load"
    2. "AppDomain" 클래스의 "CreateInstance" 및 "CreateInstanceAndUnwrap"
    3. "Type" 클래스의 "GetType"
    4. "System.AppDomain" 클래스의 "Load"
  • MSDN은 System.Reflection.Assembly 클래스의 Load 메서드를 사용하는 것을 권장

 

 

5. Get Assembly Info

class Asminfo
{
    public static object Get(System.Reflection.Assembly asm, string name)
    {
        try
        {
            Type type = asm.GetType(name);
            if (type != null)
            {
                System.Reflection.MemberInfo[] info = type.GetMembers();
                return info;
            }

            return null;
        }
        catch
        {
            return null;
        }
    }
}
class Program
{
    static void Main(string[] args)
    {
        object obj = null;
        System.Reflection.Assembly asm = null;
        System.Reflection.MemberInfo[] info = null;

        try
        {
            asm = System.Reflection.Assembly.Load("ClassLibrary1");
            obj = Asminfo.Get(asm, "ClassLib.MyClass");

            //asm = System.Reflection.Assembly.Load("ClassLibrary2");
            //obj = Asminfo.Get(asm, "ClassLibrary2.MyClass2");
            
            info = (System.Reflection.MemberInfo[])obj;

            foreach (System.Reflection.MemberInfo m in info)
            {
                Console.WriteLine(" '{0}' is a {1}", m.Name, m.MemberType);
            }

            Console.WriteLine("\nPlease Endter Key...\n");
            Console.ReadKey();
        }
        catch
        {
            //
        }
    }
}

 

 

 

 

 

 

 

 


Reference 

 - docs.microsoft.com/ko-kr/dotnet/framework/app-domains/application-domains-and-assemblies-how-to-topics

 

Link

- 도메인에 중립적인 어셈블리 : 도메인에 중립적인 어셈블리(Domain-Neutral Assembly)

- Assembly Shadow Copy : Application Domain #3 - Shadow Copy

BELATED ARTICLES

more