클래스, 구성 요소 및 컨트롤

이 항목에서는 구성 요소와 컨트롤을 정의하며 구성 요소 또는 컨트롤인 클래스를 언제 구현할지를 결정하는 데 필요한 정보를 제공합니다.

참고

이 항목에서는 Windows Forms 및 ASP.NET 클래스에 대해 설명합니다.이 항목의 내용은 WPF 클래스에 적용되지 않습니다. WPF 컨트롤 제작에 대한 자세한 내용은 컨트롤 제작 개요를 참조하십시오.

다음은 구현하기 위한 전반적인 지침입니다.

  • 클래스에서 외부 리소스를 사용하지만 이 클래스를 디자인 화면에서 사용하지 않을 경우에는 IDisposable을 구현하거나, IDisposable을 직접 또는 간접적으로 구현하는 클래스에서 파생시킵니다.

  • Windows Forms 또는 Web Forms 디자이너와 같은 디자인 화면에서 클래스를 사용하려는 경우 IComponent를 구현하거나, IComponent를 직접 또는 간접적으로 구현하는 클래스에서 파생시킵니다. IComponentIDisposable을 확장하므로 IComponent 형식은 항상 IDisposable 형식입니다. IComponent 형식은 IComponent가 아닌 IDisposable 형식보다 성능이 다소 떨어지지만 디자인 타임과 런타임에 IComponent를 사이팅하는 기능에 의해 이를 상쇄할 수 있습니다. 사이팅에 대해서는 이 항목 뒤에서 설명합니다.

  • 디자인 가능(디자인 화면에서 사용)하며 참조로 마샬링되는 클래스를 사용하려는 경우에는 Component에서 파생시킬 수 있습니다. Component는 참조로 마샬링되는 IComponent 형식의 기본 구현입니다.

  • 값으로 마샬링되는 디자인 가능한 클래스를 사용하려는 경우에는 MarshalByValueComponent에서 파생시킬 수 있습니다. MarshalByValueComponent는 값으로 마샬링되는 IComponent 형식의 기본 구현입니다.

  • 개체 모델 계층 구조에서 IComponent 형식을 사용하려는 경우 단일 상속으로 인해 Component 또는 MarshalByValueComponent 같은 기본 구현에서 파생시킬 수 없으면 IComponent를 구현합니다.

  • 사용자 인터페이스를 제공하는 디자인할 수 있는 클래스를 원하는 경우 클래스는 컨트롤이 됩니다. 컨트롤은 기본 컨트롤 클래스인 Control 또는 Control 중 하나에서 직접 또는 간접적으로 파생되어야 합니다.

    참고

    클래스가 디자인 가능하지도 않고 외부 리소스도 포함하지 않는 경우에는 IComponent 또는 IDisposable 형식이 필요하지 않습니다.

구성 요소, 컨트롤, 컨테이너 및 사이트에 대해 아래에서 정의합니다.

구성 요소

.NET Framework에서 구성 요소는 IComponent 인터페이스를 구현하거나 IComponent를 구현하는 클래스에서 직접 또는 간접적으로 파생되는 클래스입니다. 프로그래밍할 때, 구성 요소라는 용어는 다시 사용 가능하고 다른 개체와 상호 작용할 수 있는 개체를 가리킵니다. .NET Framework 구성 요소는 이러한 일반적인 요건에 맞고 외부 리소스 제어 및 디자인 타임 지원과 같은 기능도 제공합니다.

외부 리소스 제어

IComponent 인터페이스는 Dispose라는 메서드를 포함하는 IDisposable 인터페이스를 확장합니다. Dispose 메서드를 구현할 때 구성 요소가 외부 리소스를 명시적으로 해제해야 합니다. 이 방법을 사용하면 기본적으로 가비지 수집을 통해 이루어지는 불명확한 정리와는 달리 명확하게 리소스를 해제할 수 있습니다. 개발자가 해야 전파 Dispose는 구성 요소의 자식을 자원을 확보 하는 것을 확인 하는 포함 계층 구조 전체에서. 파생된 구성 요소는 해당되는 기본 클래스의 Dispose 메서드도 호출해야 합니다.

참고

Dispose 메서드를 사용하여 리소스를 명시적으로 제어하더라도 사용자가 구성 요소에서 Dispose 메서드를 호출하지 못했을 때 리소스가 영구적으로 누수되지 않도록 하기 위해 종료자(소멸자)를 통해 암시적 정리 기능을 항상 제공해야 합니다.

다음 예제에서는 기본 구성 요소 및 파생된 구성 요소에서 Dispose를 구현하는 패턴을 보여 줍니다.

public class BaseComponent : IComponent {

   // IComponent extends IDisposable.
   public void Dispose() {
        Dispose(true);
     GC.SuppressFinalize(this); 
      }

   protected virtual void Dispose(bool disposing) {
      if (disposing) {
          // Free other state (managed objects).
      }
      // Free your own state (unmanaged objects).
   }

   // Simply call Dispose(false).
      ~BaseComponent(){
      Dispose (false);
   }
}
   
// Derived component.
public class DerivedComponent : BaseComponent {
   
   protected override void Dispose(bool disposing) {
      if (disposing) {
      // Free other state.
      }
      // You must invoke the Dispose method of the base class.
      base.Dispose(disposing);
      // Free your own state.
      ...
   }
   // No finalizer/destructor.
   // No Dispose() method.
}

   
' Design pattern for a base class.
Public Class BaseComponent
   Implements IComponent
   ' Implement IDisposable
   Public Overloads Sub Dispose() 
      Dispose(True)
      GC.SuppressFinalize(Me)
   End Sub

   Protected Overloads Overridable Sub Dispose(disposing As Boolean)
      If disposing Then
         ' Free other state (managed objects).
      End If
      ' Free your own state (unmanaged objects).
      ' Set large fields to null.
   End Sub

   Protected Overrides Sub Finalize()
      ' Simply call Dispose(False).
      Dispose (False)
   End Sub
End Class

' Design pattern for a derived component.
Public Class DerivedComponent
   Inherits BaseComponent

   Protected Overloads Overrides Sub Dispose(disposing As Boolean) 
      If disposing Then 
         ' Release managed resources.
      End If
      ' Release unmanaged resources.
      ' Set large fields to null.
      ' Call Dispose on your base class.
      Mybase.Dispose(disposing)
   End Sub
   ' The derived class does not have a Finalize method
   ' or a Dispose method with parameters because it inherits
   ' them from the base class.
End Class

디자인 타임 지원

.NET Framework에서 구성 요소의 중요한 특징 중 하나는 디자인 가능하다는 점입니다. 따라서 구성 요소인 클래스를 Visual Studio 같은 RAD(신속한 응용 프로그램 개발) 환경에서 사용할 수 있습니다. 구성 요소를 Visual Studio의 도구 상자에 추가하거나 폼으로 끌어서 놓을 수 있으며 디자인 화면에서 조작할 수 있습니다. IComponent 형식에 대한 기본 디자인 타임 지원은 .NET Framework에 기본으로 적용된 기능이므로 구성 요소 개발자는 기본 디자인 타임 기능을 이용하기 위해 추가 작업을 수행할 필요가 없습니다.

디자인 타임 지원에 대한 자세한 내용은 구성 요소의 디자인 타임 특성디자인 타임 지원 확장을 참조하십시오.

구성 요소 호스팅

구성 요소는 이 항목의 뒷부분에 설명되는 컨테이너에 사이팅(호스팅)될 수 있습니다. 구성 요소가 사이팅되면, 구성 요소는 사이트(이 단원의 뒷부분에 설명)를 통해 컨테이너와 상호 작용하고 사이트를 통해 컨테이너로부터 서비스를 쿼리하거나 가져올 수 있습니다. 컨테이너가 조각날 때 리소스가 해제되도록 하려면 컨테이너에 IDisposable 인터페이스를 구현해야 합니다. Dispose 메서드를 구현할 때, 컨테이너는 보유하고 있는 모든 리소스를 해제하고 각 포함 구성 요소의 Dispose 메서드를 호출해야 합니다.

포함 관계는 논리적이므로 시각적으로 표시되지 않아도 되며, 비시각적 포함 관계의 예로 데이터베이스 구성 요소가 사이팅된 중간 계층 컨테이너를 생각할 수 있습니다. Visual Studio에서는 Windows Forms 디자이너 및 Web Forms 디자이너에서 시각적 포함 관계를 볼 수 있습니다. 시각적 디자인 화면은 폼 구성 요소(Web Forms에서는 페이지 구성 요소)를 호스팅하는 컨테이너입니다.

구성 요소 마샬링

구성 요소는 원격 가능하거나 원격 가능하지 않을 수 있습니다. 원격 가능한 구성 요소는 참조 또는 값에 의해 마샬링됩니다. 마샬링은 응용 프로그램 도메인(간단한 프로세스), 프로세스, 심지어는 컴퓨터 등의 경계를 넘어 개체를 전달하는 작업과 관련됩니다. 개체가 참조로 마샬링되는 경우에는 개체로 원격 호출하는 프록시가 만들어지고 개체가 값으로 마샬링되는 경우에는 개체의 serialize된 복사본이 관련 경계를 넘어 전달됩니다.

크기가 크거나 단일 인스턴스로 존재하는 시스템 리소스를 캡슐화하는 원격 가능한 구성 요소는 참조로 마샬링되어야 합니다. 참조로 마샬링되는 구성 요소의 기본 클래스는 Component입니다. 이 기본 클래스는 IComponent를 구현하고 MarshalByRefObject에서 파생됩니다. Control(Windows Forms 컨트롤의 기본 클래스), WebService(ASP.NET를 사용하여 만든 XML Web services의 기본 클래스), Timer(되풀이 이벤트를 생성하는 클래스) 등 .NET Framework 클래스 라이브러리에 있는 대부분의 구성 요소는 Component에서 파생됩니다.

단순히 상태만을 유지하는 원격 가능한 구성 요소는 값으로 마샬링되어야 합니다. 값으로 마샬링되는 구성 요소의 기본 클래스는 MarshalByValueComponent입니다. 이 기본 클래스는 IComponent를 구현하고 Object에서 파생됩니다. .NET Framework 클래스 라이브러리에 있는 구성 요소 중 일부만 MarshalByValueComponent에서 파생되고 이러한 구성 요소는 모두 System.Data 네임스페이스(DataColumn, DataSet, DataTable, DataViewDataViewManager)에 있습니다.

참고

값 또는 참조로 마샬링되는 개체의 기본 클래스는 각각 ObjectMarshalByRefObject이지만 해당하는 파생 클래스의 이름은 각각 MarshalByValueComponentComponent입니다.이러한 명명 스키마는 더 일반적으로 사용되는 형식에 간단한 이름을 지정합니다.

구성 요소를 원격으로 사용할 수 없을 경우에는 Component의 기본 구현에서 파생시키는 대신 IComponent를 직접 구현해야 합니다.

컨트롤

컨트롤은 사용자 인터페이스 기능을 제공하거나 사용할 수 있게 하는 구성 요소입니다. .NET Framework에서는 컨트롤에 두 개의 기본 클래스를 제공하는데 하나는 클라이언트 쪽 Windows Forms 컨트롤에 사용할 수 있고 다른 하나는 ASP.NET 서버 컨트롤에 사용할 수 있습니다. 여기에는 ControlControl이 있습니다. .NET Framework 클래스 라이브러리의 모든 컨트롤은 이러한 두 클래스에서 직접 또는 간접적으로 파생됩니다. ControlComponent에서 파생되며 UI 기능을 제공합니다. ControlIComponent를 구현하며 UI 기능을 쉽게 추가할 수 있는 인프라를 제공합니다.

참고

모든 컨트롤은 구성 요소이지만 모든 구성 요소가 컨트롤이라고 할 수는 없습니다.

컨테이너 및 사이트

Windows Forms 또는 Web Forms 페이지(ASP.NET 페이지)에 사용할 구성 요소나 컨트롤을 개발하는 경우에는 컨테이너나 사이트를 구현할 필요가 없습니다. Windows Forms 및 Web Forms용 디자이너는 Windows Forms 및 ASP.NET 서버 컨트롤의 컨테이너입니다. 컨테이너에서는 해당 컨테이너에 사이팅된 구성 요소 및 컨트롤에 서비스를 제공합니다. 디자인 타임에 컨트롤은 디자이너 안에 사이팅되며 디자이너로부터 서비스를 얻습니다. 컨테이너 및 사이트의 정의는 다음과 같습니다.

  • Container
    컨테이너는 IContainer 인터페이스를 구현하거나 이 인터페이스를 구현하는 클래스에서 파생된 클래스입니다. 논리적으로 컨테이너에는 해당 컨테이너의 자식 구성 요소라는 하나 이상의 구성 요소가 들어 있습니다.

  • Site
    사이트는 ISite 인터페이스를 구현하거나 이 인터페이스를 구현하는 클래스에서 파생된 클래스입니다. 컨테이너는 해당 자식 구성 요소와 통신하기 위해 사이트를 제공합니다. 일반적으로 컨테이너와 사이트는 하나의 단위로 구현됩니다.

참고 항목

개념

속성 개요

구성 요소의 디자인 타임 특성

기타 리소스

.NET Framework에서 사용자 지정 Windows Forms 컨트롤 개발

Developing Custom ASP.NET Server Controls

디자인 타임 지원 확장