Visual Studio 2010 & .NET 4.0 참고 자료들

Visual Studio 2010 2009. 4. 8. 16:37 Posted by 알 수 없는 사용자

안녕하세요.
아직 VSTS 2010 관련 한글 자료가 많지 않아 미리 보고 써보는게 쉽지는 않은 상황 입니다.
그렇다고 계속 기다릴 수도 없고, 비록 영문 자료지만, 충분히 보고 따라 할 수 있는 자료를 소개 합니다.

마이크로소프트의 개발자 동영상 사이트 중 절때 빠질 수 없는 채널9(Channel9)의 "Visual Studio Team System 2010 Week on Channel 9!" 시리즈가 있습니다.
여기에서 VSTS 2010의 개발 철학이나 개선되거나 추가된 기능 등에 대한 인터뷰를 볼 수 있습니다.
사실 영어가 좀 부담이 되는 부분이기는 합니다.

다음으로 좀 더 볼게 많은 "Visual Studio 2010 and the .NET Framework 4.0 Week!" 시리즈가 있습니다. VSTS 2010 오버뷰 부터 C# 4.0, C++ 10 등 보다 풍부한 볼거리를 제공합니다.

특히 C#의 아버지인 Anders Hejlsberg의 "C# 4.0 - Questions and reasons behind the answers"는 강력 추천 입니다.

그리고 마지막으로 Visual Studio 10과 .NET 4.0의 주요 내용을 에피소드로 소개하는 10-4가 있습니다.
계속 시리즈로 올라오고 있으니 꼭 참고 하시기 바랍니다. 좋은 내용들이 많이 있습니다.

감사합니다.



 

[C# 4.0] New Extension Method “Zip”

C# 2009. 4. 8. 16:10 Posted by 알 수 없는 사용자

참고 : http://blogs.msdn.com/wriju/archive/2009/02/28/c-4-0-new-extension-method-zip.aspx

저는 이 방법을 알기 전에 다음과 같은 방법을 사용 했었지요.

Web 서버에 Post 방식으로 요청을 보낼때 Query String을 사용하게 되었는데, 그 형식은 다음과 같았습니다. 
custom_action_id=1&id=330&resource_type=lot&uuid=b657895
parameter 값은 각각 Key 와  Value로 구성되어 있었습니다. 그래서 위와 같은 query string을 자동으로 계산하는 방법을 생각해 보게 되었는데요...

Select 를 이용해서 원하는 구문을 얻을 수 있었지요.  사실 linq에 익숙해지기 위해 만들어 보았을 뿐 복잡하게 할 필요는 없었습니다.

근데 C# 4.0 에서 소개된 Zip 메소드를 이용해서 다른 방법으로 바꿔 볼 수 있었습니다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            string[] parms = { "custom_action_id", "id", "resource_type", "uuid" };
            string[] values = { "1", "330", "Lot", "b53c37ed8c1f8a8075961400b1b4606eb12fd81b"};

            Console.WriteLine(ZipExtentionMethodTest(parms, values));
            Console.ReadLine();
        }

        public static string ZipExtentionMethodTest(string[] paramerters, string[] values)
        {
            // parse dict
            string ptrs = null;

            var parmStr = paramerters.Zip( values, (paramerter, value) => new
            {    
                inplace = ( values[values.Length - 1] !=  value ?
                    paramerter + "=" + value + "&" : paramerter + "=" + value
                )
            });

            foreach (var item in parmStr)
            {
                ptrs += item.inplace;
            }

            return ptrs;
        }
    }
}

위 코드랑 비교해 본다면 전 코드의 경우 Object 배열 타입의 dict란 변수를 받아서,  select  구문으로 key 와 value 값을 결합하고 인덱스가 마지막일 경우 다른 조건의 결합 을 사용하게 되어 있습니다.

그런데 Zip 코드를 이용하면, 간단히 두개의 배열로 부터 인자를 받아 하나로 합칠 수 있지요. 하지만 인덱스를 사용할 수 없어서 조건은 배열의 길이를 이용하였습니다. 

Zip을 사용하면 두개의 배열에 있는 element 들을 하나로 합칠 때 사용하면 좋은 방법이 될 것 같네요.


[MEF] 4. Import 선언

Managed Extensibility Framework 2009. 4. 7. 00:32 Posted by POWERUMC
Import 선언
 
MEF 의 구성 요소에 System.ComponentModel.Composition.ImportAttribute 특성을 선언하여 Import 를 선언할 수 있습니다. Import 는 Export 와 사용 방법이 매우 유사합니다. Import 는 프로퍼티(Properties), 필드(Fields), 생성자(Constructors) 에 선언할 수 있으며, 계약된 Export 구성 요소들을 Import 할 수 있습니다.
 
 
Property Import
 
프로퍼티로 값을 가져오기 위해 ImportAttribute 특성을 선언하면 됩니다.
 
Import 특성은 세 가지의 시그너처(Signature) 를 제공합니다.
 
public ImportAttribute();
public ImportAttribute(string contractName);
public ImportAttribute(Type contractType);
 
일반적으로 타입을 명시하지 않을 경우 프로퍼티의 타입이 Export 의 계약(Contract) 을 결정하게 됩니다.
 
아래는 프로퍼티에 Import 를 사용하는 방법입니다.
 

[Import]
MessageProcess MessageProcess { get; set; }

 
 
Field Import
 
필드의 Import 는 프로퍼티에 Import 를 선언하는 방법과 동일합니다.
 

[Import]
MessageProcess _messageProcess;

 
 
Constructor Parameters (생성자 파라메터)
 
Constructor Parameters 는 ImportingConstructor 특성을 사용하여 정의합니다. 특히 Constructor Parameters 는 여러 구성 요소를 사용하기 위해 프로퍼티 또는 필드로 선언되는 Import 의 선언을 생략할 수 있어 편리하게 사용할 수 있습니다. 또한, 암시적인 Import 가 가능하기 때문에 수동적으로 이것을 제어할 필요가 없으며, 구성 요소의 교체가 매우 용이합니다.
 
아래의 코드는 ImportingConstructor 특성을 이용하여 암시적으로 Import 하는 예입니다.
 

[Export]
public class Controller
{
   public View CurrentView { get; set; }
   public Model CurrentModel { get; set; }
 
   [ImportingConstructor]
   public Controller(View view, Model model)
   {
       this.CurrentView = view;
       this.CurrentModel = model;
   }
}

 
명시적인 Import 를 하기 위해서는 생성자 파라메터에 ImportAttribute 특성을 명시해 주면 됩니다.
 
아래는 Constructor Parameters 예의 전체 소스 코드입니다.
 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
 
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
 
namespace ImportSample
{
   class Program
   {
       [STAThread]
       static void Main(string[] args)
       {
             Program p = new Program();
             p.Run();
       }
      
       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);
 
             var controller = container.GetExportedObject<Controller>();
 
            
             Console.WriteLine(controller.CurrentView.ToString());
             Console.WriteLine(controller.CurrentModel.ToString());
       }
   }
 
   [Export]
   public class Controller
   {
       public View CurrentView { get; set; }
       public Model CurrentModel { get; set; }
 
       [ImportingConstructor]
       public Controller(View view, Model model)
       {
             this.CurrentView = view;
             this.CurrentModel = model;
       }
   }
 
   [Export]
   public class View
   {
       public override string ToString()
       {
             return "Export View";
       }
   }
 
   [Export]
   public class Model
   {
       public override string ToString()
       {
             return "Export Model";
       }
   }
}

 
실행 결과는
 
[그림1] Constructor Parameters 예제 소스 코드 실행 결과
 
 
Importing Collection
 
MEF 는 Composable Container 의 모든 Contract 의 인스턴스를 컬렉션으로 가져올 수 있습니다. MEF 는 플러그인 모델(Plugin Model) 로써 구성 요소를 교체와 추가/제거가 용이하다고 하였습니다. 이러한 구성 요소가 동적으로 교체 또는 컨테이너에 의해 관리가 되면서 구성 요소는 업데이트 또는 Recomposable(재구성 가능한) 될 수 있습니다.
 
Contract 기반의 MEF 구성 요소는 동적인(Dynamic)한 환경을 제공하며, 이것을 관리하기 위해 컬렉션으로 제어할 수 있습니다.
 
아래는 Importing Collection 의 예제 소스 코드입니다.
 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
 
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
 
namespace ImportSample
{
   class Program
   {
       [Import]
       IEnumerable<IMessageSender> MessageSenders;
 
       [STAThread]
       static void Main(string[] args)
       {
             Program p = new Program();
             p.Run();
 
             foreach (var sender in p.MessageSenders)
             {
                    sender.Say();
             }
       }
      
       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 interface IMessageSender
   {
       void Say();
   }
 
   [Export(typeof(IMessageSender))]
   public class PhoneMessageSender : IMessageSender
   {
       public void Say()
       {
             Console.WriteLine("Message Send - Phone");
       }
   }
 
   [Export(typeof(IMessageSender))]
   public class EMailMessageSender : IMessageSender
   {
       public void Say()
       {
             Console.WriteLine("Message Send - EMail");
       }
   }
}

 
IMessageSender 인터페이스를 구현한 구성 요소를 컬렉션으로 루핑하여 호출한 결과입니다.
 
[그림2] Importing Collection 예제 소스 코드 실행 결과
 
 
INotifyImportSatisfaction
 
INotifyImportSatisfaction 인터페이스는 Import 처리가 완료가 되었을 때 통보되는 인터페이스 입니다. System.ComponentModel.Composition.INotifyImportSatisfaction 인터페이스는 ImportCompleted() 메서드만 구현하면 됩니다. 클래스내 모든 Import 처리가 완료가 되었을 경우 ImportCompleted() 메서드가 호출됩니다.
 
아래 소스 코드는 INotifyImportSatisfaction 인터페이스를 구현한 예 입니다.
 

class Program : INotifyImportSatisfaction
{
 
   public void ImportCompleted()
   {
       Console.WriteLine("Completed");
   }
 
}

 
 
 
MEF 다시 보기
 
MEF 는 마치 어린 아이들이 좋아하던 조립 로봇을 보는 듯한 인상입니다. 로봇의 몸체만 있다면 팔, 다리를 끼워 로봇을 어렵지 않게 완성하는 것처럼 말입니다. 플라스틱 로봇에게 강철 옷을 입히고 싶다면, 로봇을 전부 때려부시고 새로 만들지 않고서도 MEF 를 이용하면 가능합니다. 그리고 칼과 방패를 채워주고 싶다면 그렇게 하시면 됩니다.
 
[그림3] MEF 와 조립 로봇 (그림 출처는 여기)
 
MEF 를 볼수록 하나의 작은 SOA(Service Oriented Architecture) 라고 봐도 무방할 것 같습니다. (비교하는 것이 무리이긴 하지만…) MEF 의 플러그인 모델(Plugin Model) 은 느슨한 결합(Loose Coupling) 으로 Service 와 EndPoint 의 Contract 기반의 유연한 확장성을 제공해 줍니다. 아마도 단시간내에 새로운 아키텍처의 모델로써 주목을 받을 수 있지 않을까 기대해봅니다.

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

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