[MEF] 6. Lazy Exports

Managed Extensibility Framework 2009. 4. 13. 00:38 Posted by POWERUMC
일반적인 Exports
 
Composable Part 를 구성하는 동안 특정 Part 에 대한 요청으로 객체 내부의 객체가 필요할 때가 있습니다. 만약 객체가 이런 연관 관계가 있을 경우 객체 내부에 ImportAttribute 을 선언하여 외부 Part 를 Import 할 수 있습니다. 이런 경우는 객체 내부에 Export 간의 Related 관계를 갖게 됨으로써 자동적으로 객체를 초기화할 수 있게 됩니다. ([MEF] 3. Export 선언 참조)
 
일반적인 Export 를 통해 객체 내부에 Import 를 선언하는 방법입니다.
 
class Program
{
        static void Main(string[] args)
        {
               Program p = new Program();
               p.Run();
        }
 
        void Run()
        {
               var catalog = new AggregateCatalog(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
 
               var container = new CompositionContainer(catalog);
               var batch = new CompositionBatch();
               batch.AddPart(this);
 
               container.Compose(batch);
 
               var obj = container.GetExportedObject<EmailMessageSender>();
               obj.Sender.Say();
        }
}
 
[Export]
public class MessageSender
{
        public void Say()
        {
               Console.WriteLine("Say Method");
        }
}
 
[Export]
public class EmailMessageSender
{
        [Import]
        public MessageSender Sender { get; set; }
}
 
 
Lazy Exports
 
하지만 비용이 비싼 객체를 생성할 경우 위의 [일반적인 Exports] 는 매우 비효율적일 수 있습니다. 객체 내부의 Import Object 를 사용하지 않을 가능성이 크거나, 객체의 생성 비용이 클 경우는 Lazy Export 를 고려해야 합니다. 그리고 내부 객체가 동기적(Synchronicity)이 아닌 비동기성(Asynchronism) 성격의 객체일 경우에도 반드시 필요한 기법입니다.
 
이런 경우 내부 객체의 생성을 선택적, 수동적으로 제어하여, 게으른 초기화(Lazy Initialization) 를 할 필요가 있습니다.
 
아래의 굵은 표시의 코드가 Lazy Export 로 제어하는 코드입니다.
 
class Program
{
        static void Main(string[] args)
        {
               Program p = new Program();
               p.Run();
        }
 
        void Run()
        {
               var catalog = new AggregateCatalog(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
 
               var container = new CompositionContainer(catalog);
               var batch = new CompositionBatch();
               batch.AddPart(this);
 
               container.Compose(batch);
 
               var obj = container.GetExportedObject<EmailMessageSender>();
               obj.Sender.Say();
 
               var lazyObj = container.GetExportedObject<EmailMessageSenderByLazyExport>();
               lazyObj.Sender.GetExportedObject().Say();
        }
}
 
[Export]
public class MessageSender
{
        public void Say()
        {
               Console.WriteLine("Say Method");
        }
}
 
[Export]
public class EmailMessageSender
{
        [Import]
        public MessageSender Sender { get; set; }
}
 
[Export]
public class EmailMessageSenderByLazyExport
{
        [Import]
        public Export<MessageSender> Sender { get; set; }
}
 
ImportAttribute 의 프로퍼티를 Export<T> 타입으로 변경하면 내부 객체를 GetExportedObject() 메서드를 이용하여 지연하여 객체를 생성할 수 있습니다.

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

[MEF] 8. Strongly Typed Metadata  (0) 2009.04.16
[MEF] 7. Exports and Metadata  (0) 2009.04.16
[MEF] 5. Catalog 사용  (0) 2009.04.09
[MEF] 4. Import 선언  (0) 2009.04.07
[MEF] 3. Export 선언  (0) 2009.03.29

[Blueprints] S+S Blueprints

VIsual Studio Extensibility 2009. 4. 12. 23:13 Posted by POWERUMC
새로운 트랜드 Blueprints
 
Blueprints 는 새로운 개념의 Software Factory 입니다. 언제나 우리는 반복되는 작업과 그것을 수행하기 위한 새로운 기술, 그리고 좋은 패키지를 만들기 위한 디자인, 그리고 버그를 수정하기 위한 작업을 팩토리(Factory) 라는 개념의 트랜드된 기술입니다. 팩토리(Factory) 는 Web Service, Rich Internet Application(RIA), Service Facade 를 쉽게 제공할 수 있으며 그것은 특정 프로세스, 리소스, 가이드라인, 패턴, 템플릿, 라이브러리 등이 포함됩니다.
 
Blueprints 의 팩토리는 소프트웨어 생산 공정(Software product line-SPL) 의 형태입니다. 일관된 공통적인 프로세스를 통해 패턴을 정하여 또는 공통적인 프로세스를 정의함으로써 재사용성을 높이고 체계적인 생산 공정을 정의할 수 있습니다.
 
Software Factory 는 특정 도메인 언어(Domain-Specific Language-DSLs) 를 통해 모델 기반 개발(Model-driven Development-MDD) 를 중요시하는 마이크로소프트 플랫폼을 위한 SPLs 입니다. MDD 는 Application, Services, Layers, Component 등의 복잡한 요소를 대상으로 하는데, Software Factory 는 이러한 복잡한 요소들을 단순화할 수 있습니다.
 
[그림1] Software Factory 가 생성되고 적용되는 그림
 
 
Blueprints 가 있기 까지
 
Blueprints 는 Guidance Automation Toolkit(GAT) 가 그 기반에 존재합니다. GAT 는 Microsoft 의 Pattern & Practice 팀에서 Guidance Automation(GA) 를 쉽게 적용하기 위한 툴입니다. GAT 는 Guidance Automation Extension(GAX) 를 기반으로 Web Service, Web Client, Smart Client 등 Enterprise Library 와 통합시켰고 Guidance Cunsumer 를 통해 커스터마이징이 가능한 도구입니다.
 
하지만 GAT 는 Guidance Automation(GA) 는 한계가 있었고, 이런 GAX/GAT 를 기반으로 RSS-based Factory 와 런타임 확장 및 업데이트가 가능한 새로운 서비스를 제공하게 되었습니다. 바로 이것이 S+S Blueprints 입니다.
 
S+S 는 Software plus Services 라는 의미로 Web 2.0 과 SOA 양측 모두 적용할 수 있습니다. Web 2.0 은 나은 응답성을 요구하고 SOA 는 보안과 안정성을 요구하는데, 기업은 이런 SOA 에 Web 2.0 의 응답성과 유연함의 장점을 원합니다. 이러한 Server Software base 의 IT System 은 SaaS Base 의 Web 2.0 을 지원하기 위해 Loosely connected message-passing system 의 서비스를 추가할 것입니다. 기업은 이러한 데이터 보안, 가용성, 응답성과 유연함을 원할 것입니다.
 
그리고 DSL Tools 입니다. DSL Tools 은 Visual Studio 2005 이상, Team Architect 버전에 포함된 Domain-Specific Language 를 쉽게 구현하기 위한 도구입니다. DSL 은 저렴한 비용으로 UML Modeling 을 할 수 있으며, 기업의 이해관계가 다른 (예를 들어 기업의 경영진과 실무진??) 사람과 통용할 수 있는 좋은 도구가 됩니다.
 
[그림2] 오늘날 Factory 기술의 발전
 
 
Blueprints 다운로드 받기
 
Blueprints 는 Codeplex 에서 다운로드 할 수 있습니다. 현재 Blueprints 는 November CTP Refresh 2.1.2 버전입니다.
 
Blueprints Download
 
 
Blueprints 는 Visual Studio Extensibility(VSX) 로 제작되어 Visual Studio 에 Blueprints Manager(BPM) 를 통해 실행할 수 있습니다.
 
[그림3] Blueprints Manager(BPM) 실행 화면
 
 
오늘은 Blueprints 를 소개하는 단원에서 끝내며, 추후에 Blueprints 의 Factory 를 만들고 Publish, 그리고 프로세스의 Work flow 등 보다 근접한 S+S Blueprints 를 소개해 드리도록 하겠습니다.
 
참고 문헌
 
 

Welcome to F#(3) - 사소한 탐색전.

F# 2009. 4. 12. 22:10 Posted by 알 수 없는 사용자

-관심있으면 많이 알아봐야 하는 법.
이제 F#과의 만남도 어느덧 세번째에 접어들었네요. 한 두번쯤 만나면 상대방에 대해 관심이 있는지 없는지 스스로 눈치챌 수 있겠죠. 그리고 관심이 있다면, 더 열심히 상대방에 대해서 알려고 노력하고 있을테구요. F#에 대해서 알려고 노력하다보니, F#의 4차원적인 면을 하나발견하고 잠깐 당황해서 허우적댔습니다. 거기에 대해서 짧게 적어보려 합니다.

-짧은 예제를 통해 까발려본 F#의 4차원적 특징

#light

type TwoNumbers =
    {Number1 : int; Number2 : int}

let num = {Number1 = 3; Number2 = 5}

printfn "%d %d" num.Number1 num.Number2

그리고 실행해보면 아래와 같은 결과가 나온다.


음~ 예상했던 대로 결과가 잘 나왔습니다. 그런데 왠지 타입선언과 그 타입을 실행하는 코드는 다른 소스파일에 넣는게 맞는거 같아서 타입선언을 TwoNumbers라는 파일을 생성해서 거기에 넣자는 생각이 들었죠. 그래서 C#에서 하던것 처럼 새로운 파일을 생성해서 거기에 타입선언 코드를 집어넣고, 다시 자신있게 컴파일을 실행했습니다. 그런데! 다음과 같은 오류가 발생하더군요.

오류 1 - The record label 'Number1' is not defined.

오류 2 - Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved

오류 3 - Lookup on object of indeterminate type based on information prior to this program point. A type annotation may be needed prior to this program point to constrain the type of the object. This may allow the lookup to be resolved



즉, Number1이랑 Number2가 선언되어 있는 타입을 찾을 수 없다는 말인데요. 이게 무슨 소리입니까;; 같은 솔루션에 있는 파일에 클래스의 선언을 옮겼는데 못 찾다니요..? 그런데, VisualStudio의 한지붕아래에서 살아서 전혀 눈치를 못채고 있었는데, F#의 솔루션 탐색기에는 다른 언어들과는 다른 뭔가 특별한게 있더군요. 이런 4차원 F#!!!

바로 위 그림에서 볼 수 있는 Move Up, Move Down, Add Above, Add Below말인거죠. 무슨 아이돌 그룹이라도 되는 마냥 4인조가 나란히 모여있죠. 이건 당췌 뭘까요? 아! 혹시 F#은 위에서 부터 아래로 차례대로 파일들을 컴파일 하는걸까요? 그럼 타입선언이 있는 TwoNumbers파일을 Move Up해서 다시 컴파일을 해보죠!! 자신있게 컴파일을 했건만 결과는 똑같은 에러가 납니다. 연애를 해봤거나, 작업을 절박하게 걸어본 사람은 그 사람의 성격을 알았다고 생각해서 그에 맞춰주려다가 오히려 더 곤혹스러웠던 상황이 있을겁니다.

이런. F#은 도대체 왜 이렇게 특이한걸까요? 그래서 F#을 잘아는 사람들에게 정보를 얻어보니, F#은 위에서 부터 차례대로 컴파일을 하는 건 맞는데, 그 파일들이 자동으로 하나의 모듈단위로 컴파일이 되고, 그 모듈을 이용하려면, open을 이용해서 그 모듈의 내용을 열어야 사용이 가능하다는 거 였더군요. 그래서 아래와 같이 모듈의 이름을 open해주었습니다.


#light

open TwoNumbers

let num = {Number1 = 3; Number2 = 5}

printfn "%d %d" num.Number1 num.Number2

이제 컴파일이 잘 됩니다.>_<! 모듈의 이름은 명시적으로 아래와같이,

module MyCompany.MyLibrary.MyModule

(위와 아래의 선언은 동일하다)


namespace MyCompany.MyLibrary
module MyModule =
    .......

이렇게 지정해주지 않는이상 파일이름과 동일하며, 무조건 맨 앞의 문자는 대문자가 됩니다.(즉 파일의 이름이 twoNumbers 였더라도, 모듈의 이름은 TwoNumbers가 된다는 말)

-그냥 추가로 이야기하는 공간-

type Card =
    { Number: int; Shape: int }

이렇게 타입(클래스)를 선언하고, 위 선언을 F# Interactive에서 평가하고 아래와 같은 결과가 나옵니다.

type Card =
  {Number: int;
   Shape: int;}

그리고 아래처럼 계속 평가식을 입력해보면....

> let v = {Number = 3; Shape = 5};;

val v : Card

> let a = {a = 4; b = 5};;

  let a = {a = 4; b = 5};;
  ---------^^
stdin(4,10): error FS0039: The record label 'a' is not defined.

> v;;
val it : Card = {Number = 3;
                 Shape = 5;}
>

즉, 타입이름을 명시하지 않아도 멤버의 이름과 타입을 보고 알아서 타입을 찾아서 생성한다는 겁니다. 그래서 a와 b라는 멤버로 생성하려고 했을때, 그런 멤버를 가진 타입이 없어서 에러가 발생하는 거죠.


-어디까지 4차원일까?
F#은 알면 알수록 4차원인거 같네요. 아... F#에 대해서 더 잘 알게되면 F#의 마음을 얻고 잘 지낼 수 있을까요? 일단 최대한 노력해보는 수 밖엔 없겠군요. 이렇게 짧은 탐색전을 마치겠습니다.

-참고자료
1. Expert F#, Don Syme, Adam Granicz, Antonio Cisternino, APRESS.
2. http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec2.aspx#_Toc207785764