RPNetworks.Resources - 02

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (1/4/2011 11:48:41 AM) Viewing : 2206

이전 글에 이어서 이번에는 열거형을 이용한 리소스관리를 해 보도록 하겠습니다.

이 내용은

http://www.codeproject.com/csharp/LocalizingEnums.asp

게시물의 코드를 참조했습니다.

열거형의 값을 리소스화 시켜 다국어로 보여 주는 게 되겠습니다. 참 기가막히도록 참신한 아이디어네요..

메인 클래스는 CustomResourceConverter 라는 클래스입니다.

코드 설명은 제가 만든게 아니기 때문에 생략 (ㅡ.ㅡ;;;) 합니다.

어쨋든 이 클래스를 이용하여 작업을 해보도록 하겠습니다.

이전 글에서 살펴 보았던 IShop.Resources 를 계속 사용해 보도록 하겠습니다.

아래와 같은 열거형이 있다고 가정합니다.

public enum Message
{
    Ok,
    Cancel,
    Yes,
    No
}

사용자 화면에는 Ok 의 경우 "확인" 으로 보여 주고 싶다고 합니다. 그럼 작업을 시작해 보지요.

먼저 IShop.Resources 에 아래와 같은 클래스를 생성합니다.

namespace IShop.Web
{
    public class LocalizedEnumConverter : ResourceEnumConverter
    {
        public LocalizedEnumConverter(Type type) : base(type)
        {
            base.ResourceManager = new CustomResourceManager(ResourceType.String
                              , typeof(LocalizedEnumConverter)).ResourceManager;
        }
    }
}

앞서 방법과 마찬가지로 네임스페이스 이름에 주의 하시기 바랍니다.

이제 리소스 파일을 생성해 보도록 하겠습니다.

이전에 글에서 생성하였던 리소스파일을 계속 사용합니다.

IShop.Web.String.Resources 라는 파일이 생성되었지요?

이 파일을 계속 사용합니다. 참..깜박 한 것이 있는데 이 파일의 경로는 반드시 Resources 라는 폴더에 위치해야 합니다.

즉 IShop.Resources 프로젝트에서 /Resources/IShop.Web.String.Resources 가 되겠습니다.

리소스 파일을 열고 Key 와 Value 를 입력합니다.

key:Message_Ok, value:확인
key:Message_Cancel, value:취소
key:Message_Yes, value:예
key:Message_No, value:아니오

"열거형의 이름_열겨형의 값" 형식이 됩니다.

그리고 마지막으로 열거형에 TypeConverter 특성을 붙여 줍니다.

[TypeConverter(typeof(LocalizedEnumConverter))]
public enum Message
{
    Ok,
    Cancel,
    Yes,
    No
}

이제 다 되었습니다.

이 값을 사용하기 위한 코드는 아래와 같습니다.

string ok = LocalizedEnumConverter.ConvertToString(Message.Ok);
//ok = "확인"

간단하지욤???


마지막 업데이트 : (1/5/2011 5:10:34 PM)




Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기

RPNetworks.Resources - 01

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (1/3/2011 9:34:48 PM) Viewing : 2051

이번에 알아 볼 것은 리소스 관리 입니다.

이미 예전에 리소스 관련된 글을 쓴적이 있습니다.

http://bangsil.net/MyPosts/DotNet/1a654797-8893-4c7c-9e93-c979ad67b2fa

기본적으로 리소스는 하나의 프로젝트의 Properties 라는 폴더의 하위에 위치하게 됩니다.

이 리소스는 이미지나 문자열 아이콘 파일등등 어느 것이든 가능합니다.

여러개의 프로젝트가 있는 솔루션의 경우에는 각 프로젝트마다 그 프로젝트에 해당되는 리소스가 존재하게 될테고 이를 관리 하는 것은 참 까탈스럽습니다.

그래서 이렇게 뿔뿔이 흩어져 있는 리소스를 하나의 프로젝트로 모아서 관리 할 수 있는 방법은 없을까 하고 고민하게 되었습니다.

기본적인 샘플은 위 링크에서 다운 받아서 테스트 해 보시기 바랍니다.

그리고 위 링크에서 사용되었던 버전과 달라진 점이라면 자주쓰는 데이터는 CommonMessage 형태로 따로 뽑아 두었습니다. 대부분 인증이나 게시판 관려 메시지가 되겠네요..

우선 하나씩 살펴 보도록 하겠습니다.

public enum ResourceType
{
    /// 
    /// 아이콘 타입입니다.
    /// 
    Icon = 0,
    /// 
    /// 문자열 타입입니다.
    /// 
    String,
    /// 
    /// 이미지 타입입니다.
    /// 
    Image,
    /// 
    /// Object 타입입니다.
    /// 
    Object
}

이 어셈블리를 이용하여 사용할 수 있는 리소스 형식은 위와 같습니다.

 이 어셈블리에는 중요한 클래스가 2개가 있습니다.

그중 하나는 CommonLocalizedEnumConvertoer 이며 또 하나는 CustomResourceManager 클래스입니다.

전자의 경우에는 열거형을 지역화 하는 경우에 사용하는 클래스입니다. 후자의 경우는 열거형이 아닌 경우에 사용하는 클래스입니다.

후자의 경우에는 별도로 Proxy 클래스가 필요로 합니다. 이 글의 첫 링크에 있는 예제는 바로 후자의 것이 되겠네요.

우선 CumstomResourceManager 클래스를 이용하는 법을 알아 봅시다.

public CustomResourceManager(ResourceType resourceType, Type type)
{
    bool hasResource = false;
    Assembly asm = Assembly.GetCallingAssembly();
    string resourceName = asm.GetName().Name + ".Resources." 
                        + type.Namespace + "." + resourceType.ToString();
    foreach (string reName in asm.GetManifestResourceNames())
    {
        if (reName.Substring(0, reName.LastIndexOf('.')) == resourceName)
        {
            hasResource = true;
            break;
        }
    }
    if (!hasResource)
    {
        throw new MissingManifestResourceException("해당 타입의 리소스를 찾을 수 없습니다.");
    }
    else
    {
        rm = new ResourceManager(resourceName, asm);
    }
}

ResourceType은 앞서 보았던 열거형입니다.
즉 매개변수로 해당 리소스 파일이 있는지 찾고 찾게 되면 ResourceManger 의 인스턴스를 생성하는 코드가 되겠습니다.

이 룰에 적합하게 하기 위해서는 리소스파일의 경우 {네임스페이스}.String.{CultureCode(생략가능)}.resources  형식이 되어야 합니다.

또 다른 생성자는 각 네임스페이스의 리소스가 아니라 공용리소스를 생성하기위한 생성자입니다.

이 클래스에는 리소스를 가져오는 여러 메서드가 있습니다만 대동소이합니다.

예를 들어 리소스를 문자열로 가져오기 위해서는 GetString 메서드를 호출합니다 코드는 아래와 같습니다.

public string GetString(string key)
{
    if (key.Length == 0)
    {
        return null;
    }
    try
    {
        return rm.GetString(key);
    }
    catch
    {
        return null;
    }
}

이제 실제로 사용해보도록 하겠습니다.

앞서 잠깐 언급했듯이 이 클래스를 이용하기 위해서는 Proxy 클래스가 필요합니다.

예를 들어 I-Shop  이라는 쇼핑몰 프로젝트를 한다고 칩니다.

그러면 이 솔루션에 해당되는 리소스를 담당하는 하나의 프로젝트를 생성합니다.

예를 들면 IShop.Resources 라는 프로젝트가 되겠습니다.

이 프로젝트는 RPNetworks.Resources 어셈블리를 참조해야 합니다.

프로젝트를 생성했으면 우선 리소스 파일을 생성합니다. 리소스 파일은 Resourcer.net 을 이용하면 편리합니다.

예를 들어 IShop.Web 이라는 프로젝트의 리소스 파일을 생성한다고 칩시다.

리소스 파일의 이름은 IShop.Web.String.resources 가 되겠습니다. 만약 영문이라면 IShop.Web.String.en.resources 가 될테고 문자열리소스가 아니라 이미지 리소스 라면 ISHop.Web.Image.resources 가 될것입니다.

이제 이 프로젝트에 proxy 클래스를 만들어 보겠습니다.

namespace IShop.Web
{
    public class StringProxy
    {
        private static CustomResourceManager rm;

        /// 
        ///  클래스의 정적 생성자입니다.
        /// 
        static StringProxy()
        {
            rm = new CustomResourceManager(ResourceType.String, typeof(StringProxy));
        }
        public static string Download_Migration_01
        {
            get { return rm.GetString("Download_Migration_01"); }
        }
    }
}

1행을 보면 IShop.Web 입니다.

네임스페이스는 현재 네임스페이스가 아니라 이 리소스를 사용할 곳의 네임스페이스를 지정해 주어야 합니다.
IShop.Web 이라는 프로젝트의 문자열 리소스 Proxy 클래스라는 의미가 되겠습니다.

이렇게 proxy 클래스를 생성하게 되면 코드에서는 StringProxy.Download_Migration_01 처럼 사용할 수 있게 됩니다.

간단하지욤?

다음에는 열거형을 사용하는 법을 알아 보도록 하겠습니다.


마지막 업데이트 : (1/5/2011 5:12:26 PM)




첨부 파일 보기 (1)
Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기

Nunit에서 HttpContext.Current 값 얻어 오기

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (12/7/2010 2:42:56 PM) Viewing : 2692

요즘 단위 테스트에 열을 내고 있습니다..^^;

실제로 플젝에서 단위테스트를 적용해 보기는 지금이 처음이네요..

생각 보다 벽이....높고 넘어야 할 산도 많더군요..쿨럭..

그래도 MVC 의 경우 단위테스트에 용이하도록 설계가 되어 있기에 도전을 해 보았습니다.

몇 차례에 걸쳐 개발하다가 막혔던 부분에 대해서 알아 보도록 하겠습니다.

대부분의 내용은 프로 ASP.NET MVC 프레임워크 라는 책과 구글링에서 나온 것이고 제 머리에서도 약간 나왔습니다만..별거는 없다는....

먼저 환경을 얘기해 보면

ASP.NET MVC 2로 개발된 프로젝트를 단위 테스트 할 것이며, Nunit와 Moq 프레임워크를 사용할 것입니다.

처음에 가장 애를 먹었던...HttpContext.Current 값을 얻어 오는 것에 대해 알아 보겠습니다.

단위 테스트를 해보신 분은 아시겠지만..단위테스트 시에는 Context가 NULL 이 됩니다.

그러나 코드 상에서는 Context개체를 자주 사용하죠..Reqeust, Response, Session, Server 등등의 속성들이 이에 해당되겠습니다.

MVC에서 Context 개체는 2개가 있습니다. 하나는 HttpContext 클래스의 정적 속성인 Current 로 얻어 오는 HttpContext 개체가 있으며 Controller의 추상 클래스인 ControllerBase클래스의 속성인 ControllerContext 로 얻어 오는 ControllerContext 라는 개체가 있습니다.

실제로 런타임시에는 이 값이 같습니다. - 이 2개의 타입은 다른 타입이며 모두 같은 속성을 가지고 있지는 않습니다만 공통된 속성의 경우 값이 같습니다.

그러나 단위테스트에서는 엄연히 다른 타입이라...달리 구성해주어야 합니다. 이를 고려해서 개발시에 하나만 사용하여도 문제는 없으리라 보지만...어쨋든...

이에 대한 글은 구글에서 많이 찾아 볼수 있지만.. 거의 쓸모가....ㅡ.ㅡ;;;;

제가 선택한 코드는 아래 링크와 같습니다.

http://www.jasonbock.net/jb/Default.aspx?blog=entry.161daabc728842aca6f329d87c81cfcb

namespace UCMessenger.Tests.MockObjects
{
    /// 
    /// http://www.jasonbock.net/jb/Default.aspx?blog=entry.161daabc728842aca6f329d87c81cfcb
    /// 
    public class MockHttpContext
    {
        // NOTE: This code is based on the following article:
        // http://righteousindignation.gotdns.org/blog/archive/2004/04/13/149.aspx
        private const string ContextKeyAspSession = "AspSession";
        private const string ThreadDataKeyAppPath = ".appPath";
        private const string ThreadDataKeyAppPathValue = "c:\\inetpub\\wwwroot\\webapp\\";
        private const string ThreadDataKeyAppVPath = ".appVPath";
        private const string ThreadDataKeyAppVPathValue = "/webapp";
        private const string WorkerRequestPage = "default.aspx";

        private HttpContext context = null;

        /// 
        /// Initializes a new instance of the  class.
        /// 
        public MockHttpContext()
        {
            Thread.GetDomain().SetData(MockHttpContext.ThreadDataKeyAppPath
                                    , MockHttpContext.ThreadDataKeyAppPathValue);
            Thread.GetDomain().SetData(MockHttpContext.ThreadDataKeyAppVPath
                                    , MockHttpContext.ThreadDataKeyAppVPathValue);
            SimpleWorkerRequest request = new WorkerRequest(
                 MockHttpContext.WorkerRequestPage, string.Empty, new StringWriter(), false);
            this.context = new HttpContext(request);

            HttpSessionStateContainer container = new HttpSessionStateContainer(
                Guid.NewGuid().ToString("N"),
                new SessionStateItemCollection(),
                new HttpStaticObjectsCollection(),
                5,
                true,
                HttpCookieMode.AutoDetect,
                SessionStateMode.InProc,
                false);

            HttpSessionState state = Activator.CreateInstance(
                 typeof(HttpSessionState),
                 BindingFlags.Public | BindingFlags.NonPublic |
                 BindingFlags.Instance | BindingFlags.CreateInstance,
                 null,
                 new object[] { container }, CultureInfo.CurrentCulture) as HttpSessionState;
            this.context.Items[ContextKeyAspSession] = state;
        }

        /// 
        /// 현재 컨텍스트 정보를 가져옵니다.
        /// 
        /// The context.
        public HttpContext Context
        {
            get
            {
                return this.context;
            }
        }

        /// 
        /// 
        /// 
        private class WorkerRequest : SimpleWorkerRequest
        {
            private bool isSecure = false;

            public WorkerRequest(string page, string query, TextWriter output, bool isSecure)
                : base(page, query, output)
            {
                this.isSecure = isSecure;
            }

            public override bool IsSecure()
            {
                return this.isSecure;
            }
        }
    }
}

사실 HttpContext.Current 의 참조만 얻기 위해서는 아래와 같은 간단한 코드로도 가능합니다.

HttpContext.Current = new HttpContext(new HttpRequest(
             null, "http://tempuri.org", null), new HttpResponse(null));

그러나 여기서 HttpContext.Current.Session 의 참조를 얻기 위해서는 골치가 아프더군요.

그래서 위의 링크 처럼 하게 되면 일단 Session 의 참조까지는 가능합니다.

단위 테스트 코드에서 Context의 참조를 얻기위한 코드는 아래와 같습니다.

/// 
/// 이 메서드는 Test 메서드 호출 전에 호출되는 메서드 입니다.
/// 
[SetUp]
public void SetUp()
{
    HttpContext.Current = (new MockHttpContext()).Context;
    Utility.SetBoardCategoryCache();
    Utility.SetPostCategoryCache();
} 

위 코드는 SetUp 특성이 붙어 있어 해당 클래스에 있는 단위 테스트 메서드를 실행하기 전에 실행되는 메서드입니다.
7행에 보시면 Current 값을 얻어 오는 것을 볼 수 있습니다.


마지막 업데이트 : (1/5/2011 5:17:08 PM)




Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기

RPNetworks.Configuration - 03

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (12/4/2010 3:39:38 PM) Viewing : 1640

이번에는 dbConnection 에 대해서 알아 보도록 하겠습니다.

config 파일 안에는 아래와 같이 구성되어 있습니다.


 
  
   
   
  
 

dbConnection 섹션에는 connectionStrings 컬렉션 밖에 없습니다.

이 컬렉션은 db연결 문자열을 가지고 있습니다.

이 섹션 값을 코드 상에서 직접 볼일은 아마도 웹폼에서는 없을 듯 합니다.윈폼에서는 있겠죠..

RPNetworks.Core - SqlDB 클래스 에서 아래와 같은 코드가 있었습니다.

public SqlDB(string connectionString)
{
    this.connection = new SqlConnection(ConfigurationHelper.GetConnectionString(connectionString));
}

 이 코드는  config에 정의된 연결문자열의 이름 (name 속성) 을 인풋으로 받으면 이를 복호화 하여 SqlConnection 개체를 만드는 코드 입니다.

여기서 사용되는 ConfigurationHelper.GetConnectionString() 메서드가 오늘 살펴볼 가장 중요한 메서드입니다.

그 전에 connectionStrings 의 요소의 속성들에 대해서 잠깐 살펴 보겠습니다.

name 은 키값입니다. 당연히 유일해야 겠죠.

connectionString은 암호화된 문자열입니다.

securityType 는 암호화할 타입입니다.

이는 RPNetworks.Security.SecurityType 열거형의 Int32값입니다. 그 내용은 아래와 같습니다.

public enum SecurityType
{
    /// 
    /// 아리아 알고리즘입니다.
    /// 
    AriaAlgorithm = 0,
    /// 
    /// 시드 알고리즘입니다.
    /// 
    SeedAlgorithm,
    /// 
    /// 128비트 MD5 알고리즘입니다.
    /// 
    MD5,
    /// 
    /// 128비트 SHA1 알고리즘입니다.
    /// 
    SHA1,
    /// 
    /// 256비트 SHA256 알고리즘입니다.
    /// 
    SHA256
}

연결 문자열은 복호화가 가능하여야 하므로 securityType 은 항상 0 아니면 1이어야 겠자만. SEED 보다는 ARIA가 더 빠릅니다.그래서 전 0을 선호합니다.

마지막으로 keySize는 암호화할 키 사이즈입니다. 암호화 형식에 따라 128, 256 등등이 있습니다.
이 부분은 각 암호화 클래스를 참고 하십시오.

이제 GetConnectionString 메서드를 살펴 보도록 하겠습니다.

public static string GetConnectionString(string connectionStringName)
{
    if (ConfigurationHelper.ConnectionHash != null)
    {
        if (ConfigurationHelper.ConnectionHash[connectionStringName] != null)
        {
            return ConfigurationHelper.ConnectionHash[connectionStringName].ToString();
        }
    }
    else
    {
        ConfigurationHelper.ConnectionHash = new Hashtable();
    }
    string returnValue = string.Empty;

    DBConnectionSection section = ConfigurationHelper.Ancestor.DbConnectionSection;
    if (section == null)
    {
        return String.Empty;
    }
    if (!String.IsNullOrEmpty(section.ConnectionStrings[connectionStringName].Parameters["securityType"]))
    {
        if (String.IsNullOrEmpty(section.ConnectionStrings[connectionStringName].Parameters["keySize"]))
        {
            section.ConnectionStrings[connectionStringName].Parameters["keySize"] = "128";
        }

        try
        {
            object secuityProviderBase = null;
            Assembly asm = ConfigurationHelper.IsWebForm 
               ? Assembly.LoadFrom(HttpContext.Current.Server.MapPath("/bin/RPNetworks.Security.dll")) 
               : Assembly.LoadFrom("RPNetworks.Security.dll");
            MethodInfo[] methodInfos = asm.GetType("RPNetworks.Security.SecurityProviderBase")
                                       .GetMethods(BindingFlags.Static | BindingFlags.Public);
            for (int i = 0; i < methodInfos.Length; i++)
            {
                if (methodInfos[i].GetParameters().Length == 2)
                {
                    secuityProviderBase = methodInfos[i].Invoke(null, new object[] { 
                         Convert.ToInt32(section.ConnectionStrings[connectionStringName]
                                                             .Parameters["securityType"]), 
                         Convert.ToInt32(section.ConnectionStrings[connectionStringName]
                                                             .Parameters["keySize"]) 
                    });
                    break;
                }
            }

            if (secuityProviderBase != null)
            {
                MethodInfo info1 = secuityProviderBase.GetType().BaseType.GetMethod("CreateMasterKey");
                info1.Invoke(secuityProviderBase, new object[] { connectionStringName });
                info1 = secuityProviderBase.GetType().BaseType.GetMethod("DecryptFromString");
                returnValue = info1.Invoke(secuityProviderBase, new object[] {
                    section.ConnectionStrings[connectionStringName].Parameters["connectionString"] 
                }).ToString();
            }
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
    else
    {
        returnValue = section.ConnectionStrings[connectionStringName].Parameters["connectionString"];
    }
    ConfigurationHelper.ConnectionHash[connectionStringName] = returnValue;
    return returnValue;
}

ConfigurationHelper.ConnectionHash 라는 해쉬테이블은 한번 읽어온 연결 문자열을 저장해 놓기 위해 사용합니다.

30행 부터는 config에 정의된 값을 기반으로 리플렉션을 이용하여 윈폼과 웹폼일때 각 해당 폴더에 Security.dll 파일을 읽어와서 DecryptFromString() 메서드를 호출하여 복호화 하는 일련의 과정입니다.

복호화가 되면 이를 해쉬 테이블에 저장합니다.

해쉬테이블에 저장하는 이유는 연결 문자열은 아주 빈번하게 사용되지만 이를 호출시 마다 리플렉션을 이용하여 복호화 하는 것은 힘겹기 때문입니다. 이때문에 최초에 한번 복호화 하여 이를 저장한다면 이후 부터는 바로 이 값을 가져다 쓰게 되니 복호화 과정이 생략되게 되는 겁니다.

이리 하여 복호화 된 연결 문자열을 얻게 되었습니다.


마지막 업데이트 : (1/5/2011 5:22:11 PM)




Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기

RPNetworks.Configuration - 02

현재 주소 복사
트랙백 주소 복사
방실이님의 글 (12/4/2010 2:29:38 PM) Viewing : 1579

이전글 에서 밝혔듯이 projectInfo 부터 살펴 보도록 하겠습니다.

이 클래스는 한 가지 이유 때문에 생성되었습니다.

이 Configuration 이라는 어셈블리를 생성한 이유는 여러 프로젝트에서 공용으로 쓰기 위함이었습니다.

대부분 db연결이라든지 monitoring 관련해서는 공통되지만 분명 해당 프로젝트에 따라 새로 추가되어야 하는 섹션들은 존재 할 것입니다.

이전 글의 예에서 NetworkSection 처럼 말이죠.

해당 섹션 클래스는 새로운 프로젝트를 생성하여 그 안에 생성 할 수 있습니다.

예를 들면 프로젝트 이름이 MyProject 라면 MyProject.Configruation 이라는 어셈블리를 생성할 수 있으며 이 어셈블리는 RPNetworks.Configration을 참조 하여 상속 받으면 됩니다.

그런데 문제는 이렇게 생성된 Section의 특정 값에 접근을 하기 위해서는 ConfigurationHelper 라는 클래스를 통해서만이 가능합니다.

NetworkSection의 경우라면 ConfigrationHelper.Network 처럼 접근을 해야 한다는 얘기죠.

그러면 섹션이 새로 생길때마다 ConfigurationHelper 클래스에 Property를 생성해주어야 한다는 의미가 되겠습니다.

이는 재사용성에 큰 문제가 발생하게 됩니다.

그래서 고안해 낸게 바로 이번 글에서 살펴보게 될 ProjectInfoSection 입니다.

config의 설정을 보게 되면 다음과 같습니다.

<projectInfo sectionGroupName="myProject" version="1.0.0.0" lastUpdate="2010년 07월 11일 13시 25분 18초"/>

여기서 version과 lastUpdate는 별 의미는 없습니다. 배포시에 수정하고 런타임시에 프로그램(웹이든 윈폼이든)에서 해당 값을 보여 줄수 있습니다. 필요하다면 말이죠.

중요한 것은 sectionGroupName 이 되겠습니다.

여기서 설정한 이름은 실제로 config에서 <rpnetworks> 아래 섹션그룹으로 등록됩니다.

이전 글 예시에서 확인해 볼 수 있습니다.

이렇게 생성해 놓으면 MyProject.Configuration에 위치하는 NetworkSection에 다음과 같이 접근이 가능하게 됩니다.

string domain = ConfigurationHelper.Project.GetSection("network").GetParameter("domain");

자. 이제 ConfigurationHelper클래스에는 Project 라는 Property가 하나만 있으면 언제든지 동적으로 해당 MyProject.Configuration의 해당 값을 얻어 올 수 있습니다.

ProjectInfoSection 클래스는 아래와 같이 간략하게 구성되어 있습니다.

public class ProjectInfoSection : CustomConfigurationSection
{
    /// <summary>
    /// 섹션그룹이름으로 사용할 현재 프로젝트의 이름을 가져옵니다.
    /// </summary>
    /// <value>The name of the project section group.</value>
    [ConfigurationProperty("sectionGroupName", IsRequired = true)]
    public string ProjectSectionGroupName
    {
        get
        {
            return (string)base["sectionGroupName"];
        }
    }

    /// <summary>
    /// 마지막 업데이트 일시를 가져오거나 설정합니다.
    /// </summary>
    /// <value>The last update.</value>
    [ConfigurationProperty("lastUpdate", IsRequired = true)]
    public string LastUpdate
    {
        get
        {
            return (string)base["lastUpdate"];
        }
        set
        {
            base["lastUpdate"] = value;
        }
    }

    /// <summary>
    /// 업데이트 완료 버전을 가져오거나 설정합니다.
    /// </summary>
    /// <value>The version.</value>
    [ConfigurationProperty("version", DefaultValue = "1.0.0.0")]
    public string Version
    {
        get
        {
            return (string)base["version"];
        }
        set
        {
            base["version"] = value;
        }
    }
}

여기서 버전에 대한 값을 가져 오기 위해서는 http://bangsil.net/Tag/Configuration 를 읽어 보신분은 알겠지만

다음과 같이 읽어 올수 있습니다.

 string version = ConfigurationHelper.ProjectInfoSection.Version;

마지막 업데이트 : (12/4/2010 2:29:38 PM)




Trackback 보기 (0)
댓글 보기 (0)
댓글 쓰기



<< < 1 2 3 4 5 6 7 8 9 10 > >>