Programming/.NET
애플리케이션이 빌드되는 경우에는 해당 애플리케이션의 모든 파일을 컴파일 하지는 않습니다. 특히 App_Code 폴더에는 여러 코드화 파일이 들어가 있는데 만약 이 폴더에 특정 파일을 추가하게 되면 이 파일들은 자동으로 컴파일되어 애플리케이션 내에서 바로 사용할 수 있게 됩니다.

다만 모든 파일이 컴파일 대상이 아니므로 어떤 파일은 빌드하고난 뒤에도 dll에 속하지 않고 따로 남아있거나 혹은 단순히 복사되는 경우도 있는데 실제 어떤 파일을 컴파일할것인가는 C:\Windows\Microsoft.NET\Framework\v4\Config 에 있는 ASP.NET 마스터 web.config에 다음과 같이 정의되어 있습니다.
<compilation>
    <buildProviders>
        <add extension=".aspx" type="System.Web.Compilation.PageBuildProvider" />
        <add extension=".ascx" type="System.Web.Compilation.UserControlBuildProvider" />
        <add extension=".master" type="System.Web.Compilation.MasterPageBuildProvider" />
        <add extension=".asmx" type="System.Web.Compilation.WebServiceBuildProvider" />
        <add extension=".ashx" type="System.Web.Compilation.WebHandlerBuildProvider" />
        <add extension=".soap" type="System.Web.Compilation.WebServiceBuildProvider" />
        <add extension=".resx" type="System.Web.Compilation.ResXBuildProvider" />
        <add extension=".resources" type="System.Web.Compilation.ResourcesBuildProvider" />
        <add extension=".wsdl" type="System.Web.Compilation.WsdlBuildProvider" />
        <add extension=".xsd" type="System.Web.Compilation.XsdBuildProvider" />
        <add extension=".js" type="System.Web.Compilation.ForceCopyBuildProvider" />
        <add extension=".lic" type="System.Web.Compilation.IgnoreFileBuildProvider" />
        <add extension=".licx" type="System.Web.Compilation.IgnoreFileBuildProvider" />
        <add extension=".exclude" type="System.Web.Compilation.IgnoreFileBuildProvider" />
        <add extension=".refresh" type="System.Web.Compilation.IgnoreFileBuildProvider" />
        <add extension=".edmx" type="System.Data.Entity.Design.AspNet.EntityDesignerBuildProvider" />
        <add extension=".xoml" type="System.ServiceModel.Activation.WorkflowServiceBuildProvider, System.WorkflowServices, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
         <add extension=".svc" type="System.ServiceModel.Activation.ServiceBuildProvider, System.ServiceModel.Activation, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
         <add extension=".xamlx" type="System.Xaml.Hosting.XamlBuildProvider, System.Xaml.Hosting, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
    </buildProviders>
</compilation>
<코드 1-1>

buildProviders라고 되어 있는 이것을 빌드공급자라고 하며 위에서 정해진 해당 항목이 빌드 대상임을 의미합니다. 빌드공급자 자체는 Sytem.Web.Compilation.BuildProvider 에서 상속된 클래스이며 코드1-1 항목들중
<add extension=".aspx" type="System.Web.Compilation.PageBuildProvider" /> 
<코드 1-2>

코드1-2는 aspx파일을 BuildProvider에서 상속된 PageBuildProvider 클래스를 사용해 컴파일함을 의미합니다. 컴파일 하는것 이외에 애플리케이션에 단순히 포함되어야만 하는 경우도 있습니다. 예를 들면
<add extension=".js" type="System.Web.Compilation.ForceCopyBuildProvider" />
<코드 1-3>

코드 1-3은 ForceCopyBuildProvider 클래스로서 지정된 js파일은 컴파일 대상이 아닌 빌드시 빌드결과물에 복사하여 이동시킬 대상인 것입니다. 또 다른 빌드공급자 항목을 살펴보면
<add extension=".exclude" type="System.Web.Compilation.IgnoreFileBuildProvider" />
<코드 1-4>

코드 1-4는 IgnoreFileBuildProvider 로서 컴파일이나 복사가 아닌 아예 빌드과정에서 제외되어야할 항목임을 의미합니다.

이러한 특징을 이용하면 일부원하는 파일을 임의로 빌드대상에 포함시킬 수도 있는데 그 방법은 15와 같습니다.
<add extension=".txt" type="System.Web.Compilation.ForceCopyBuildProvider" />
<코드 1-5> 

위와 같이 항목을 임의로 추가시키게 되면 txt파일은 애플리케이션 빌드시 복사대상에 자동적으로 포함시킬 수 있게 됩니다.

빌드 공급자를 필요에 의해 단일적으로 추가시키거나 혹은 삭제하는 것이 아닌 아예 자신만의 빌드공급자를 생성하여 추가시킬 수도 있습니다. 예를 들어 .cli 확장자를 가진 파일에 대해 관련 클래스를 동적으로 생성하고 애플리케이션 단위에서 사용하고자 한다면 다음과 같이 .cli 파일의 구조를 정의하고
<?xml version="1.0" encoding="utf-8" ?>
<cli name="myCli">
  <name>cliel</name>
  <site>cliel.com</site>
</cli>

<코드 1-6>

.cli 확장자를 붙여 정의한 파일을 저장한 뒤 이렇게 생성한 파일을 읽어들여 동적으로 클래스를 만들어 주는 빌드공급자 클래스를 코드 1-7처럼 작성해야 합니다.

namespace myCliass
{
    public class cli : BuildProvider
    {
        public override void GenerateCode(AssemblyBuilder myCli)
        {
            XmlDocument xml_cli = new XmlDocument();

            using (Stream cli_file = OpenStream())
            {
                xml_cli.Load(cli_file);
            }

            XmlNode cliNode = xml_cli.SelectSingleNode("/cli");
            string str_cliNode = cliNode.Attributes["name"].Value;

            XmlNode titleNode = xml_cli.SelectSingleNode("/ci/title");
            string str_titleNode = cliNode.InnerText;

            XmlNode siteNode = xml_cli.SelectSingleNode("/cli/site");
            string str_siteNode = cliNode.InnerText;

            CodeCompileUnit ccu = new CodeCompileUnit();
            CodeNamespace cn = new CodeNamespace();
            CodeMemberProperty cmp1 = new CodeMemberProperty();
            CodeMemberProperty cmp2 = new CodeMemberProperty();

            cn.Imports.Add(new CodeNamespaceImport("System"));
            cmp1.Name = "title";
            cmp1.Type = new CodeTypeReference(typeof(string));
            cmp1.Attributes = MemberAttributes.Public;
            cmp1.GetStatements.Add(new CodeSnippetExpression("return \"" + str_titleNode + "\""));

            cmp2.Name = "site";
            cmp2.Type = new CodeTypeReference(typeof(string));
            cmp2.Attributes = MemberAttributes.Public;
            cmp2.GetStatements.Add(new CodeSnippetExpression("return \"" + str_siteNode + "\""));

            CodeTypeDeclaration ctd = new CodeTypeDeclaration(str_cliNode);
            ctd.Members.Add(cmp1);
            ctd.Members.Add(cmp2);

            cn.Types.Add(ctd);
            ccu.Namespaces.Add(cn);

            myCli.AddCodeCompileUnit(this, ccu);
        }
    }
}
<코드 1-7>

이 공급자 클래스는 App_Code에 .cli 파일이 추가되면 해당 파일을 읽어들여 동적으로 클래스를 생성하고 애플리케이션에서 새롭게 생성된 클래스를 즉시 사용할 수 있도록 합니다. 이러한 빌드공급자 클래스는  BuildProvider 클래스를 상속받아 GenerateCode 메서드를 재정의 하는 방법으로 생성합니다.

GenerateCode 메서드에는 AssemblyBuilder 클래스가 붙는데 이 클래스는 System.Web.Compilation 안에 있으므로 using 을 통해 System.Web.Compilation 네임스페이스를 참조하도록 해야 합니다.

코드 1-7클래스는 xml 형태의 .cli 파일을 읽고 파일에 정의된 이름(name="myCli")의 클래스를 생성하며 해당 클래스에 각 속성(title / site)을 추가하도록 작성되었습니다.

웹애플리케이션에서는 Web.config 파일을 수정하여 .cli 에 대한 빌드공급자를 생성하고
<system.web>
  <compilation debug="true" targetFramework="4.0">
    <buildProviders>
     <add extension=".cli" type="myCliass.cli" />
    </buildProviders>
  </compilation>
</system.web>
코드 1-7에서 만들어진 클래스를 사용하고자 하는 애플리케이션에서 참조추가합니다. 이 후 App_Code 폴더에 .cli 파일을 넣으면 비로소 다음과 같이 클래스를 사용할 수 있게 됩니다.

 

'Programming > .NET' 카테고리의 다른 글

[ASP.NET] 폴더 구조  (1) 2013.12.12
[ASP.NET] Label  (0) 2013.12.11
[ASP.NET] 빌드공급자  (0) 2013.12.10
[ASP.NET] 페이지 구조  (0) 2013.12.09
[ASP.NET] 지시문  (0) 2013.12.07
[ASP.NET] 포스트백(PostBack)  (0) 2013.12.05
0 0