첨부 실행 코드는 나눔고딕코딩 폰트를 사용합니다.
728x90
반응형
728x170

■ 규칙 엔진을 만드는 기본적인 방법을 보여준다.

Image11.png
0.01MB

▶ User.cs

namespace TestProject;

/// <summary>
/// 사용자
/// </summary>
public class User
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Property
    ////////////////////////////////////////////////////////////////////////////////////////// Public

    #region 성명 - Name

    /// <summary>
    /// 성명
    /// </summary>
    public string Name { get; set; }

    #endregion
    #region 나이 - Age

    /// <summary>
    /// 나이
    /// </summary>
    public int Age { get; set; }

    #endregion
}

 

▶ Operator.cs

using System.Reflection;

namespace TestProject;

/// <summary>
/// 연산자
/// </summary>
public static class Operator
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Field
    ////////////////////////////////////////////////////////////////////////////////////////// Static
    //////////////////////////////////////////////////////////////////////////////// Private

    #region Field

    /// <summary>
    /// 함수 딕셔너리
    /// </summary>
    private static Dictionary<string, Func<object, object, bool>> _functionDictionary;

    /// <summary>
    /// 속성 정보 딕셔너리
    /// </summary>
    private static Dictionary<string, PropertyInfo> _propertyInfoDictionary;

    #endregion

    //////////////////////////////////////////////////////////////////////////////////////////////////// Constructor
    ////////////////////////////////////////////////////////////////////////////////////////// Static

    #region 생성자 - Operator()

    /// <summary>
    /// 생성자
    /// </summary>
    static Operator()
    {
        _functionDictionary = new Dictionary<string, Func<object, object, bool>>();

        _functionDictionary["greater_than"] = new Func<object, object, bool>(ProcessOperatorGreaterThan);
        _functionDictionary["equal"       ] = new Func<object, object, bool>(ProcessOperatorEqual);

        _propertyInfoDictionary = typeof(User).GetProperties().ToDictionary(propInfo => propInfo.Name);
    }

    #endregion

    //////////////////////////////////////////////////////////////////////////////////////////////////// Method
    ////////////////////////////////////////////////////////////////////////////////////////// Static
    //////////////////////////////////////////////////////////////////////////////// Public

    #region 적용하기 - Apply(user, opertatorName, propertyName, targetValue)

    /// <summary>
    /// 적용하기
    /// </summary>
    /// <param name="user">사용자</param>
    /// <param name="opertatorName">연산자명</param>
    /// <param name="propertyName">속성명</param>
    /// <param name="targetValue">타겟 값</param>
    /// <returns>적용 결과</returns>
    public static bool Apply(User user, string opertatorName, string propertyName, object targetValue)
    {
        return _functionDictionary[opertatorName](GetPropertyValue(user, propertyName), targetValue);
    }

    #endregion

    //////////////////////////////////////////////////////////////////////////////// Private

    #region 속성 값 구하기 - GetPropertyValue(user, propertyName)

    /// <summary>
    /// 속성 값 구하기
    /// </summary>
    /// <param name="user">사용자</param>
    /// <param name="propertyName">속성명</param>
    /// <returns>속성 값</returns>
    private static object GetPropertyValue(User user, string propertyName)
    {
        PropertyInfo propertyInfo = _propertyInfoDictionary[propertyName];

        return propertyInfo.GetGetMethod(false).Invoke(user, null);
    }

    #endregion

    #region 연산자 >> 처리하기 - ProcessOperatorGreaterThan(source1, source2)

    /// <summary>
    /// 연산자 >> 처리하기
    /// </summary>
    /// <param name="source1">소스 객체 1</param>
    /// <param name="source2">소스 객체 2</param>
    /// <returns>처리 결과</returns>
    private static bool ProcessOperatorGreaterThan(object source1, object source2)
    {
        if(source1 == null || source2 == null || source1.GetType() != source2.GetType() || !(source1 is IComparable))
        {
            return false;
        }

        return (source1 as IComparable).CompareTo(source2) > 0;
    }

    #endregion
    #region 연산자 == 처리하기 - ProcessOperatorEqual(source1, source2)

    /// <summary>
    /// 연산자 == 처리하기
    /// </summary>
    /// <param name="source1">소스 객체 1</param>
    /// <param name="source2">소스 객체 2</param>
    /// <returns>처리 결과</returns>
    private static bool ProcessOperatorEqual(object source1, object source2)
    {
        return source1 == source2;
    }

    #endregion
}

 

▶ Program.cs

namespace TestProject;

/// <summary>
/// 프로그램
/// </summary>
class Program
{
    //////////////////////////////////////////////////////////////////////////////////////////////////// Method
    ////////////////////////////////////////////////////////////////////////////////////////// Static
    //////////////////////////////////////////////////////////////////////////////// Private

    #region 프로그램 시작하기 - Main()

    /// <summary>
    /// 프로그램 시작하기
    /// </summary>
    private static void Main()
    {
        User user = new User() { Age = 16, Name = "John" };

        Console.WriteLine(Operator.Apply(user, "greater_than", "Age", 15));
        Console.WriteLine(Operator.Apply(user, "greater_than", "Age", 17));

        Console.WriteLine(Operator.Apply(user, "equal", "Name", "John"));
        Console.WriteLine(Operator.Apply(user, "equal", "Name", "Bob" ));
    }

    #endregion
}
728x90
반응형
그리드형(광고전용)
Posted by icodebroker

댓글을 달아 주세요