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 의 방법을 제공해 주게 됩니다.
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 |