[MEF] 3. Export 선언

Managed Extensibility Framework 2009. 3. 29. 21:03 Posted by POWERUMC
Exports 선언
 
MEF 는 Export 를 통해 외부로 구성요소를 노출할 수 있습니다. Export 는 System.ComponentModel.Composition.ExportAttribute 특성을 통해 선언합니다. 이 특성은 클래스 뿐만 아니라 프로퍼티와 메서드에도 선언을 할 수 있습니다.
 
 
구성요소 Export 하기
 
ExportAttribute 특성을 사용하여 아래와 같이 구성요소를 외부로 노출하게 됩니다. ExportAttribute 은 몇 가지의 시그너처(Signature) 를 제공하는데 매개변수를 생략하게 될 경우 MEF 은 클래스의 타입으로 Contract 를 매핑하게 됩니다.
 
[Export]
class MessageSender
{
 
}
 
 
프로퍼티 Export
 
프로퍼티를 Export 하는 방법입니다. 프로퍼티를 Export 할 수 있게 되어 여러 가지 면에서 유리할 수 있습니다.
 
Core CLR 이 제공하는 타입(Type) 뿐만 아니라 외부의 다양한 타입(Type) 을 사용할 수 있습니다. 프로퍼티에 Export 를 선언할 수 있음으로써 Export 를 구조적으로 분리하여 단순화 할 수 있습니다. 그러므로 같은 구성요소 내에서 Export 간의 Related 관계를 가질 수 있습니다.
 
아래의 코드와 같이 Timeout 프로퍼티는 Contract 를 맺게 됩니다.
 
public class Configuration
{
   [Export("Timeout")]
   public int Timeout
   {
       get { return int.Parse(ConfigurationManager.AppSettings["Timeout"]); }
   }
}
 
[Export]
public class UsesTimeout
{
   [Import("Timeout")]
   public int Timeout { get; set; }
}
 
 
메서드 Export
 
구성요소의 메서드를 Export 할 수 있습니다. 메서드의 Export 는 기본적으로 대리자(Delegate) 를 통해 호출하게 됩니다. 메서드를 Export 하게되면 보다 더 세세한 제어를 가능하게 하고, 심플하게 방법으로 Code Generating 이 가능합니다.
 
public class MessageSender
{
   [Export(typeof(Action<string>))]
   public void Say(string message)
   {
       Console.WriteLine(message);
   }
}
 
[Export]
public class MessageProcess
{
   [Import(typeof(Action<string>))]
   public Action<string> MessageSender { get; set; }
 
   public void Send()
   {
       MessageSender("Call send process in MessageProcess");
   }
}
 
그리고 ExportAttribute 은 타입(Type) 대신 문자열을 사용하여 Contract 를 사용할 수 있습니다.
 
public class MessageSender
{
   [Export("MessageSender")]
   public void Say(string message)
   {
       Console.WriteLine(message);
   }
}
 
[Export]
public class MessageProcess
{
   [Import("MessageSender")]
   public Action<string> MessageSender { get; set; }
 
   public void Send()
   {
       MessageSender("Call send process in MessageProcess");
   }
}
 
 
아래의 소스 코드는 이번 예제에서 사용된 전체 소스 코드입니다.
namespace ExportSample
{
   class Program
   {
       [Import]
       MessageProcess MessageProcess { get; set; }
 
       [STAThread]
       static void Main(string[] args)
       {
             Program p = new Program();
             p.Run();
 
             p.MessageProcess.Send();
       }
 
       private void Run()
       {
             var catalog = new AggregateCatalog();
             catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
 
             var container = new CompositionContainer(catalog);
             var batch = new CompositionBatch();
             batch.AddPart(this);
             container.Compose(batch);
       }
   }
 
   public class MessageSender
   {
       [Export("MessageSender")]
       public void Say(string message)
       {
           Console.WriteLine(message);
       }
   }
 
   [Export]
   public class MessageProcess
   {
       [Import("MessageSender")]
       public Action<string> MessageSender { get; set; }
 
       public void Send()
       {
             MessageSender("Call send process in MessageProcess");
       }
   }
}
 
 
Export 요약
 
이렇게 ExportAttribute 을 사용하여 Contract 를 제공하는 것은 굉장히 중요한 의미를 가지게 됩니다. 플러그인 모델(Plugin Model) 에서 Export 는 구성요소를 외부로 노출하는, 즉 Contract 의 방법을 제공해 주게 됩니다.
 
http://blog.powerumc.kr/upload/Image/NET/NET-Framework/MEF1/capture1.jpg
 
Contract 맺음으로써 개발자는 Contract Base 로 단지 Contract 만 제공받으면 됩니다. 이러한 Contract 는 제한된 상호작용을 극복하여 대부분의 커플링(Coupling)을 해소할 수 있으며, 플로그인 모델(Plugin Model) 에서 보다 쉽게 구성요소를 캡슐화 할 수 있습니다.

'Managed Extensibility Framework' 카테고리의 다른 글

[MEF] 6. Lazy Exports  (0) 2009.04.13
[MEF] 5. Catalog 사용  (0) 2009.04.09
[MEF] 4. Import 선언  (0) 2009.04.07
[MEF] 2. Parts 와 Contracts 선언  (0) 2009.03.22
[MEF] 1. Managed Extensibility Framework 이란?  (2) 2009.03.16