6.4.1 Generic 라이브러리 만들기

.NET 리모팅 서비스를 제공할 때는 서비스 측과 클라이언트 측에서 공통으로 사용하는 라이브러리가 필요합니다. GenericWebRobotLib 이름의 클래스 라이브러리 프로젝트를 추가합시다.

.NET 리모팅 서비스에서 제공하는 클래스는 MashalByRefObject를 파생한 형식이어야 합니다.

public class GenericWebRobot:MarshalByRefObject
{

}

WebRobotLib를 클라이언트 측에 제공하는 것은 기술을 유출하는 것이므로 여기에서는 리플렉션으로 WebRobotLib를 사용하기로 할게요.

리플렉션으로 WebRobotLib 어셈블리를 로딩하고 WebCollect 형식 개체를 생성하여 여러 메서드에서 이를 이용해야 하므로 WebCollection 개체와 WebCollect 형식의 리플렉션한 Type 개체를 멤버 필드로 선언할게요. WebRobotLib를 참조하여 사용할 것이 아니라 어셈블리를 동적으로 로딩하여 사용할 것이므로 WebCollect 형식 명을 코드에서 사용할 수 없으며 object 형식의 멤버 필드를 선언할게요.

object instance = null;
Type type = null;

생성자에서는 WebRobotLib 어셈블리를 동적으로 로딩하고 WebCollect 개체를 생성하는 작업과 WebCollect 형식의 리플렉션 Type 개체를 구하는 일을 수행합니다.

public GenericWebRobot()
{
    Assembly asm = Assembly.Load("WebRobotLib");
    instance = asm.CreateInstance("WEB_Robot_Lib.WebCollect");
    type = asm.GetType("WEB_Robot_Lib.WebCollect");
}

수집할 대상의 Seed 사이트에서 상대적 깊이 상한을 설정하는 메서드를 제공합시다. 동적으로 로딩하여 생성한 개체와 리플렉션 Type을 이용하여 WebCollect의 Depth 속성의 리플렉션 PropertyInfo 개체를 얻어와서 값을 설정합니다.

public void SetDepth(int depth)
{
    PropertyInfo pi = type.GetProperty("Depth");
    pi.SetValue(instance, depth,null);
}

수집할 대상의 Seed 사이트에서 상대적 깊이 상한을 얻어오는 메서드도 제공합시다. 마찬가지로 WebCollect의 Depth 속성의 리플렉션 PropertyInfo 개체를 얻어와서 값을 구하여 반환합니다.

public int GetDepth()
{
    PropertyInfo pi = type.GetProperty("Depth");
    return (int)pi.GetValue(instance,null);
}

수집 주기를 설정하는 메서드를 제공합니다. 마찬가지로 WebCollect의 Period 속성의 리플렉션 PropertyInfo 개체를 얻어와서 수집 주기를 설정합니다.

public void SetPeriod(int period)
{
    PropertyInfo pi = type.GetProperty("Period");
    pi.SetValue(instance, period, null);
}

수집 주기를 얻어오는 메서드를 제공합시다. WebCollect의 Period 속성의 리플렉션 속성 개체를 얻어와서 수집주기를 얻어와 반환합니다.

public int GetPeriod()
{
    PropertyInfo pi = type.GetProperty("Period");
    return (int)pi.GetValue(instance, null);
}

같은 원리로 수집 가동 시작과 멈춤을 설정하는 메서드와 수집 가동 여부를 얻어오는 메서드를 제공하세요.

public void SetEnabled(bool enabled)
{
    PropertyInfo pi = type.GetProperty("Enabled");
    pi.SetValue(instance, enabled, null);
}

public bool GetEnabled()
{
    PropertyInfo pi = type.GetProperty("Enabled");
    return (bool)pi.GetValue(instance, null);
}

Seed 사이트를 추가하는 메서드를 제공합시다. WebCollect 형식의 AddSeedSite 메서드의 리플렉션 MethodInfo 개체를 얻어와서 Invoke합니다.

public void SetSeedSite(string url)
{
    MethodInfo mi = type.GetMethod("AddSeedSite");
    object[] objs = new object[1] { url };
    mi.Invoke(instance, objs);
}

▷ GenericWebRobot.cs

using System;
using System.Reflection;
 
namespace GenericWebRobotLib
{
    /// <summary>
    /// 웹 로봇 서비스 제공 클래스
    /// </summary>
    public class GenericWebRobot:MarshalByRefObject
    {
        object instance = null;
        Type type = null;
        /// <summary>
        /// 생성자
        /// </summary>
        public GenericWebRobot()
        {
            Assembly asm = Assembly.Load("WebRobotLib");
            instance = asm.CreateInstance("WEB_Robot_Lib.WebCollect");
            type = asm.GetType("WEB_Robot_Lib.WebCollect");            
        }
        /// <summary>
        /// 수집 상대적 깊이 상한 설정 메서드
        /// </summary>
        /// <param name="depth">상대적 깊이</param>
        public void SetDepth(int depth)
        {
            PropertyInfo pi = type.GetProperty("Depth");            
            pi.SetValue(instance, depth,null);
        }
        /// <summary>
        /// 수집 상대적 깊이 상한 얻어오기 메서드
        /// </summary>
        /// <returns>상대적 깊이 상한</returns>
        public int GetDepth()
        {
            PropertyInfo pi = type.GetProperty("Depth");
            return (int)pi.GetValue(instance,null);
        }

        /// <summary>
        /// 수집 주기 설정 메서드
        /// </summary>
        /// <param name="period">수집 주기</param>
        public void SetPeriod(int period)
        {
            PropertyInfo pi = type.GetProperty("Period");
            pi.SetValue(instance, period, null);
        }

        /// <summary>
        /// 수집 주기 얻어오기 메서드
        /// </summary>
        /// <returns>수집 주기</returns>
        public int GetPeriod()
        {
            PropertyInfo pi = type.GetProperty("Period");
            return (int)pi.GetValue(instance, null);
        }


        /// <summary>
        /// 수집 가동 시작 및 멈춤 메서드
        /// </summary>
        /// <param name="enabled">수집 가동 여부</param>
        public void SetEnabled(bool enabled)
        {
            PropertyInfo pi = type.GetProperty("Enabled");
            pi.SetValue(instance, enabled, null);
        }
        /// <summary>
        /// 수집 가동 여부 확인 메서드
        /// </summary>
        /// <returns>수집 가동 여부</returns>
        public bool GetEnabled()
        {
            PropertyInfo pi = type.GetProperty("Enabled");
            return (bool)pi.GetValue(instance, null);
        }
        /// <summary>
        /// Seed 사이트 등록 메서드
        /// </summary>
        /// <param name="url">사이트 주소</param>
        public void SetSeedSite(string url)
        {
            MethodInfo mi = type.GetMethod("AddSeedSite");
            object[] objs = new object[1] { url };
            mi.Invoke(instance, objs);
        }
    }
}