Tech/Silverlight2011. 6. 22. 16:52

Silverlight 5에는 3D 그래픽 기능이 추가되었습니다. (기존에는 Silverlight에서 자체적으로 지원하지는 않고 서드파티 라이브러리만 있었습니다Silverlight 5 3D 그래픽은 XNA 그래픽 라이브러리를 사용하며 GPU 가속이 지원됩니다.

XNA는 
내부적으로 DirectX의 일부 기능을 사용하기 때문에 사용 환경에 제약이 있습니다.
 

  • DirectX 9.0 이상
  • Windows XP 이상 (XP, Vista, 7)
     

사용법은 직접 다루지는 않고 링크로 대체하도록 하겠습니다.

3D
튜토리얼

http://silverlight.bayprince.com/tutorials.php

 

3D 데모

http://david.blob.core.windows.net/babylon/Babylon.html

마우스를 이용해 카메라 시점을 변경할 있고 키보드 화살표를 이용해 이동할 있습니다.

 

Silverlight 3D 참고 자료: http://msdn.microsoft.com/en-us/library/gg197424(v=XNAGameStudio.35).aspx

Posted by 알 수 없는 사용자
Tech/Silverlight2011. 6. 22. 15:58

Silverlight 5에는 동영상을 재생할 하드웨어(GPU; 그래픽카드 ) 이용해 CPU 부하를 줄이는 기술이 추가되었습니다.

 

하드웨어 가속을 사용하는 법은 간단합니다.

실버라이트 파일(.xap) 파일을 명시한 <object> 태그 안에 <param>으로 enableGPUAcceleration 속성을 주면 됩니다.


enableGPUAcceleration 자체는 Silverlight 5 이전에도 원래 있었던 속성이고, 바뀐 점은 속성을 켰을 동영상 재생 GPU 가속을 사용하게 되었다는 점입니다.


Silverlight 5 Beta 이뤄진 간단한 성능 테스트입니다.

번째 사진은 Silverlight 없이 미디어 플레이어로 동영상을 재생했을 ,

번째 사진은 GPU 가속 없이 Silverlight 동영상을 재생했을 ,

번째 사진은 GPU 가속을 켜고 Silverlight 동영상을 재생했을 ,

번째 사진은 GPU 가속과 함께 BitmapCache 사용했을 때의 CPU 사용도입니다.

(높이가 낮을 수록 좋고, 좌우 길이는 성능과 관계 없습니다)


번째 사진과 비교했을 , GPU 가속을 것과 켜지 않은 것의 차이가 생각보다 크지 않은 것을 있습니다. 하지만, BitmapCache 사용했을 때는 CPU 사용도가 크게 낮아진 것을 확인할 있습니다.

BitmapCache 동영상 디코딩 자체에 영향을 주지는 않습니다만 GPU 가속을 사용할 함께 사용하면 이점이 있다고 합니다. (자세한 것은 아래의 원문을 참고하세요)

출처: http://mtaulty.com/CommunityServer/blogs/mike_taultys_blog/archive/2011/05/03/silverlight-5-beta-rough-notes-hardware-decoded-h-264.aspx

하드웨어 가속 디코딩에 대해서는 정식 릴리즈가 나올 때까지 많은 개선이 이루어질 거라고 생각하기 때문에, 이후 정식 버전을 기대해 봐야겠습니다.


 MediaElement BitmapCache 적용하는 방법은 다음과 같습니다.
 


캐시에 대한 다른 의견도 있습니다. 저사양 컴퓨터에서 MediaElement 캐시를 사용하면 성능이 하락한다는 의견인데 확인해 필요가 있을 같습니다.

출처: http://msdn.microsoft.com/en-us/library/ee309563(v=VS.96).aspx#1

Posted by 알 수 없는 사용자
Tech/Silverlight2011. 6. 21. 15:04

Silverlight 5(Beta) 동영상 재생 속도 조절 기능이 추가되었습니다.

MediaElement PlaybackRate 속성을 설정함으로써 쉽게 재생 속도를 조절할 있습니다.


PlaybackRate
의 값은 배속을 나타내며, 값이 2이면 2배속(2x), 0.5면 0.5배속(0.5x)으로 동작합니다.

이를 이용해서 배속 조절이 가능한 간단한 동영상 재생기를 만들어 보겠습니다.
 


위와
같이 동영상을 재생할 MediaElement 하나와 재생 속도를 조절할 Slider 하나를 만들고

MediaElement PlaybackRate 속성에 Slider Value 바인드하고 실행하면,


슬라이더를 이용해 동영상 재생 속도를 조절할 있는 동영상 재생기가 완성됩니다!

'Tech > Silverlight' 카테고리의 다른 글

[Silverlight 5] 3D 그래픽  (1) 2011.06.22
[Silverlight 5] GPU 가속 동영상 재생  (0) 2011.06.22
[Silverlight MEF - Export UserControl]  (2) 2010.06.02
[Silverlight MEF - Dynamic XAP Loading]  (1) 2010.05.12
Posted by 알 수 없는 사용자
IT 이야기2010. 6. 21. 11:18

비즈니스 애플리케이션을 위한 Silverlight 4

 

세가지 테마

u  비즈니스 어플리케이션 강화 - Rich Text Area

u  미디어 강화

u  Beyond the Brower - 웹브라우저를 벗어난 기능을 지원. 로컬자원접근, 로컬 api와 연동

 

공통된 사용자들의 요구사항

u  Dragging Files into Silverlight

u  Right Click Support

u  Printing Support - 브라우저 지원의 프린트가 아님

 

프린팅

u  비주얼 트리내의 오브젝트를 대상으로 프린트가 가능함.

 

미디어

u  멀티캐스트지원.

u  DRM지원. 오프라인도 지원함.

u  Mp4 DRM지원(H.264, AAC-LC)

u  웹캠지원

n  캠과 마이크 사용가능

n  보안을 이유로 사용시 다이얼로그로 확인.

 

RichTextArea&BiDi

u  Read Only or Editable

u  Content Model

n  Runs, Spans & Paragraphs

u  Hyperlinks

u  Embedded Elements

u  Multi-level Undo

u  FlowDirection - 글자의 흐름을 제어하여, 아랍권 언어(Right to Left) 지원.

 

새로운 브라우저 지원

u  Google Chrome

 

Other Core Runtime Feature Callouts

u  Controls

n  마우스 휠 버튼의 대폭 지원

n  런타임에 포함된 ViewBox

u  Graphics

n  Extended PNG지원

n  CompositeTransform

u  other

n  NGEN of Platform Assemblies

n  닷 넷 4 지원.

 

Out of Browser Enhancements

u  OS상의 경고 창을 띄우는 것이 가능함.

u  윈도우의 위치나 크기 조절 지원.

u  html Brush

u  HTML로딩이 가능함. 보안상의 이유로 Out of Browser에서만 지원.

u  플래시 등의 오브젝트가 포함된 페이지도 로딩 가능함.



 

Posted by 알 수 없는 사용자
Tech/Silverlight2010. 1. 1. 14:21

Commands in Silverlight with SLExtensions - 1에서 이어집니다.

일단, 앞에서 새로 빌드한 SLExtensions.dll 파일을 프로젝트 참조에 추가해두고 다음으로 넘어가도록 합시다.

커맨드 제공자

첫 번째로는 커맨드들을 모아 둘 Commands 라는 정적 클래스를 만듭니다. 가령 무엇인가 삭제하는 Delete 라는 커맨드를 만든다고 하면 다음과 같은 Commands 클래스가 만들어지게 됩니다.

public static class Commands
{
public static Command DeleteCommand { get; private set; }

static Commands()
{
DeleteCommand = new Command("DeleteCommandName");
}
}

정적 생성자에서 정적 속성인 DeleteCommand를 초기화하는 것을 볼 수 있습니다. Command 개체의 생성자에 넣는 커맨드 이름은, 사용하려는 커맨드 이름과 동일하게 "DeleteCommand"라고 지정하는 것이 보통이겠으나 여기서는 확실히 구분을 주기 위해서 "DeleteCommandName"이라고 지정해 보았습니다.


ViewModel 연결

ViewModel 에서는 삭제 커맨드가 실행되었을 때 뭔가 삭제하는 작업을 수행해주어야 되겠죠. 커맨드가 실행되었다는 것을 알기 위해서 다음과 같이 생성자에서 Executed 이벤트를 구독합니다.

public MainPageViewModel()
{
Commands.DeleteCommand.Executed += new EventHandler<ExecutedEventArgs>(DeleteCommand_Executed);
}

DeleteCommand_Executed 라는 메서드에서 삭제 작업을 수행해 줄 것이라고 기대할 수 있겠습니다.


View 연결

이제 View에서 커맨드를 발생시키도록 합니다. 먼저 커맨드 관련 클래스들이 포함되어 있는 SLExtensions.Input 네임스페이스를 추가합니다.

xmlns:input="clr-namespace:SLExtensions.Input;assembly=SLExtensions"

다음으로는 삭제 버튼에 삭제 커맨드를 지정해줍니다.

<Button Content="Delete" input:CommandService.Command="DeleteCommandName"/>

DeleteCommandName 이라는 문자열을 사용해서 실행될 커맨드를 지정하고 있습니다. 이제 이 버튼을 클릭하면 삭제 커맨드가 실행되는 것이지요.


View - ViewModel 연결

한 번 실행해보기 위한 작업을 해 봅시다. 일단 ViewModel의 DeleteCommand_Executed 메서드에서 메시지 박스를 띄우도록 합니다.

void DeleteCommand_Executed(object sender, ExecutedEventArgs e)
{
MessageBox.Show("DeleteCommand");
}

그리고 View 생성 시 ViewModel이 같이 생성되도록 View의 xaml 파일을 수정합니다. 일단 프로젝트의 네임스페이스를 추가하고,

xmlns:local="clr-namespace:SilverlightApplication3"

ViewModel을 생성하도록 데이터 컨텍스트를 추가합니다. UserControl 태그의 여는 태그 바로 아래에 다음과 같은 내용을 추가합니다.

<UserControl.DataContext>
<
local:MainPageViewModel />
</
UserControl.DataContext>

이제 프로젝트를 실행해서 삭제 버튼을 누르면 메시지 박스가 뜨는 것을 볼 수 있을 것입니다.


이번에는 커맨드 패턴을 이용하여 어떻게 View와 ViewModel을 연결시키는지 간단히 살펴보았습니다. 다음 연재에서 좀 더 상세한 내용을 다뤄보도록 하겠습니다.

'Tech > Silverlight' 카테고리의 다른 글

[Silverlight Custom Font 적용]  (0) 2010.01.12
Custom Animation in Silverlight  (1) 2010.01.06
Commands in Silverlight with SLExtensions - 1  (0) 2009.12.26
Silverlight Pixel Shader 개발 팁  (0) 2009.10.28
Posted by wafe
Tech/Silverlight2009. 12. 26. 20:40

커맨드 패턴이 뭔지에 대한 설명은 생략하고 다짜고짜 들어가보도록 하겠습니다.

왜 커맨드 패턴인가?

보통 WPF/Silverlight에서는 Presentation Model 패턴(흔히 MVVM 패턴)을 써서 GUI(View)와 프로그램 상태(ViewModel)를 분리합니다. Binding 이라는 기술적인 개념 덕분에 xaml.cs 파일에는 코드 한 줄 쓰지 않고도 View와 ViewModel을 연결할 수가 있고, View와 ViewModel이 서로를 몰라도 되는 상황을 유지할 수 있습니다. 그런데 이건 보여주는 기능에만 해당되는 얘기일 뿐 사용자가 버튼을 클릭했을 때 발생하는 이벤트를 처리한다거나 하는 일을 위해서는 xaml.cs(View)에서 코드를 통해 ViewModel의 메서드를 호출해 줘야 합니다.

커맨드 패턴을 사용하면 View와 ViewModel의 분리 상태를 유지하면서 View에서 발생한 이벤트를 ViewModel로 알려줄 수 있게 됩니다.

준비 사항

Silverlight 4 이전 버전에서 커맨드 패턴을 사용하려면 SLExtensionsComposite Client Application Guidance(Prism) 라이브러리를 사용하면 됩니다. MS의 patterns & practices 그룹에서 발표한 Prism을 쓰고 싶었지만 단지 커맨드 패턴만을 쓰기 위해서는 프레임워크도 그렇고 문서도 그렇고 너무 방대해서 짧은 시간에 파악하기 힘들었습니다. 그래서 이번에는 SLExtensions를 사용해보도록 하겠습니다.

SLExtensions 다운로드 페이지에서 받을 수 있는 알파 릴리즈를 사용하면 Blend에서 프로젝트를 열였을 때 다음과 같은 에러가 발생하면서 XAML을 로드할 수 없게 됩니다.

A command with the same name '{0}' is already registered.

Blend에서 더미 데이터가 채워져 있는 GUI를 보면서 디자인 할 수 있다는 건 상당한 장점인데, 그러한 장점을 못쓰게 된다는 것은 뼈아픈 일이지요. 다행히 최신 소스 코드(현재 Changeset 35533)에서는 이 문제가 해결되어 있습니다.

일단 Source Code 페이지 우측의 Latest Version Download 링크에서 최신 버전 소스를 받습니다. 압축을 풀면 나오는 소스에서 trunk/SLExtensions/SLExtensions 폴더의 프로젝트를 빌드해서 사용하면 됩니다. 빌드된 dll 파일은 ClientBin 폴더에 생성됩니다.


다음 연재 : Commands in Silverlight with SLExtensions - 2

'Tech > Silverlight' 카테고리의 다른 글

Custom Animation in Silverlight  (1) 2010.01.06
Commands in Silverlight with SLExtensions - 2  (0) 2010.01.01
Silverlight Pixel Shader 개발 팁  (0) 2009.10.28
[Element Binding]  (0) 2009.10.12
Posted by wafe
Tech/Silverlight2009. 10. 28. 01:25
요즘 HLSL을 가지고 Pixel Shader를 만들고 있다. 따라서 여기서 얘기하는 경험은 HLSL로 된 *.fx 파일을 컴파일 할 때 적용되는 얘기이다. 셰이더 어셈블리 명령을 직접 써서 만드는 일은 전혀 해보지 않아서 얼마나 관련성이 있을지 모르겠다.

Silverlight 3와 WPF(.NET 3.5 SP1)에서는 Shader Model 2의 Pixel Shader(ps_2_0)를 지원한다.

Pixel Shader 2.0에서는 64개의 산술 instruction만을 사용할 수 있다. 문제는 64개를 넘어서 컴파일이 안 될 때만 인스트럭션 개수를 알려준다는 것. 기본적인 사용법만 배운 상태에서 한참 만들다가 "님, 인스트럭션 개수 초과했어염. 65개임."하는 에러 메시지를 받았을 때 어찌나 황당하던지.

인스트럭션 개수를 알 수 있는 방법을 찾아 헤매다가 발견한 것이 셰이더 어셈블리 파일을 만들어 내는 옵션이다. *.fx 파일을 fxc.exe로 컴파일할 때 /Fc 옵션을 사용하면 어셈블리 파일을 출력해준다. 여기에는 컴파일 결과물의 인스트럭션 개수가 표시되기 때문에 작업할 때 아주 유용하다. 만세! 인스트럭션 개수를 알 수 있는 다른 방법은 아직 찾지 못했다.

인스트럭션 개수를 알 수 있는 방법이 생기니 인스트럭션 개수 줄이는 삽질도 이제 좀 할 맛이 난다. 경험상 현재까지 작업중에 인스트럭션 줄이는데 제일 도움이 되는 것은 똑같은 산술 연산을 벡터 연산 하나로 합치는 거였다.

가령 이런 코드보다
float c1 = Const1 - color.r;
float c2 = Const2 - color.g;
float c3 = Const3 - color.b;
이런 코드의 인스트럭션 개수가 적었다.
float4 c4 = {Const1, Const2, Const3, 0.0f};
float4 c = c4 - color;

 

'Tech > Silverlight' 카테고리의 다른 글

Commands in Silverlight with SLExtensions - 2  (0) 2010.01.01
Commands in Silverlight with SLExtensions - 1  (0) 2009.12.26
[Element Binding]  (0) 2009.10.12
[Blend 3 Element Binding]  (0) 2009.10.12
Posted by wafe
Tech/Silverlight2009. 8. 3. 13:06
Deep Zoom 강좌 by ONESTONE


1. 개별 이미지의 위치 정보 얻기


1. 개별 이미지의 위치 정보 얻기

- Deep Zoom Composer를 통해 내보내기 한 결과물에서 Metadata.xml 파일을 보면 다음과 같은 정보를 얻을 수 있다.


AspectRatio : 전체 이미지의 Width / Height 비율
x, y : 이미지의 위치, 1을 기준으로 비율에 맞추어 변경한 값
width, height : 이미지의 크기, 1을 기준으로 비율에 맞추어 변경한 값

하지만 MultiScaleImage 컨트롤은 Metadata.xml 파일을 사용하는 것이 아니라, 추가적으로 내보내기 되는 dzc_output.xml 파일을 사용한다.

- dzc_output.xml 파일에서는 다음과 같은 정보를 얻을 수 있다.

Size : 원본 이미지의 Width, Height
Viewport.Width : 원본 이미지를 얼마만큼 확대/축소 하였는지 나타나는 비율
Viewport.X, Y : Viewport.Width의 비율에 따라서 이미지의 X, Y 위치, 1을 기준으로 비율에 맞추어 변경한 값

- 실제 개별 이미지의 영역 정보를 얻기 위해서는 MultiScaleImage 컨트롤로 부터 얻을 수 있는 MultiScaleSubImage들의 Collection을 이용하면 된다. 이것은 MultiScaleImage의 SubImages를 통해서 얻을 수 있다. 얻은 Collection은 MultiScaleImage의 Collection이고 각각의 MultiScaleImage에서 위에서 얻을 수 있는 Viewport Width, X, Y 정보를 얻을 수 있게 된다.

- SubImage의 Viewport 정보를 이용해서 SubImage의 X, Y, Width, Height는 다음과 같이 계산할 수 있다.

- 위 식을 이용하여 특정 Point가 속해 있는 SubImage를 얻는 코드는 다음과 같다.

<MultiScaleImage x:Name="msi" ... />

Point pt = msi.ElementToLogicalPoint(구하기 원하는 Point)
foreach (MultiScaleSubImage subImage in msi.SubImages)
{
if (pt.X >= -subImage.ViewportOrigin.X / subImage.ViewportWidth &&
    pt.X <= -subImage.ViewportOrigin.X / subImage.ViewportWidth + 1 / subImage.ViewportWidth &&
    pt.Y >= -subImage.ViewportOrigin.Y / subImage.ViewportWidth &&
    pt.Y <= -subImage.ViewportOrigin.Y / subImage.ViewportWidth + 1 / subImage.ViewportWidth / subImage.AspectRatio)
{
// 찾았다!!!
}
}



'Tech > Silverlight' 카테고리의 다른 글

[Behavior 만들기]  (0) 2009.10.01
[MVVM/Command Pattern]  (0) 2009.10.01
Silverlight 3 _ 3D  (0) 2009.06.18
ImageButton 만들기  (0) 2009.06.11
Posted by 알 수 없는 사용자
Tech/Silverlight2009. 5. 15. 18:41
Rhino Mocks 홈페이지

1. What is Rhino Mocks?
2. 설치
3. Silverlight Unit에서 사용하기
4. Example

1. What is Rhino Mocks?

A dynamic mock object framework for the .Net platform. It's purpose is to ease testing by allowing the developer to create mock implementations of custom objects and verify the interactions using unit testing.

Licensing: Rhino Mocks is Free Software which is released under the BSD license.




2. 설치


Rhino Mocks 3.5 - For Silverlight 

위의 파일을 받아서 압축을 풀어보면 다음과 같은 파일이 들어 있는 것을 확인할 수 있다.


테스트 프로젝트의 참조에 Rhino.Mocks 3.5 Silverlight.dll을 포함시키고 using Rhino.Mocks를 추가하면 된다.




3. Silverlight Unit에서 사용하기


Rhino Mocks를 사용하기 위해서는 다음을 지켜야 한다.

1. Mock Object로 만들 대상 Class의 함수가 상속 가능해야 한다. (virtual)

2. MockRepository에 Mock Object에 대한 선언이 끝나면 ReplayAll을 호출한다.

3. Test가 끝나면 VerifyAll을 호출해 정의한 대로 실행되었는지 확인한다.

 - VerifyAll을 호출하였을 때 정의한 대로 실행되지 않았다면 Test Fail이 발생한다.


Rhino Mocks로 클래스/인터페이스를 Mocking하기 위해서 다음과 같은 절차를 거친다.

1. MockRepository를 만든다.
ex. MockRepository mocks = new MockRepository();

2. 클래스인 경우에 PartialMock, 인터페이스인 경우에 StrickMock을 이용해 MockObject를 만든다.
ex. ContentsPlayerMain cpMain = mocks.PartialMock<ContentsPlayerMain>();

Mock Object에서 가상으로 사용할 함수를 선언한다.

return value가 있을 경우 _ Expect.Call(function)
return value가 void인 경우 _ Expect.Call(delegate{function;}) or ...; LastCall

-

Expect.Call의 Return 결과물에 새로운 Return Value나 함수 호출 횟수를 설정할 수 있다.

Expect.Call(function).Return(data); - function을 호출하면 data가 return 된다.

Expect.Call(function).Repeat.Once() - function이 한 번만 실행되는 것을 확인한다.

-

Mock Object에서 Expect.Call로 정의된 함수를 호출하게 되면 실제 Class의 해당 함수의 동작을 따르는 것이 아니라 정의한 함수의 동작을 따르게 된다.
ex. Expect.Call(cpMain.GetSynchronizeData(15)).Return(data); 
// GetSynchronizeData 함수에 15가 인자로 들어오면 data를 return 한다.

참고 자료) Rhino Mocks 3.3 Quick Reference.pdf




4. Example


- 다음과 같은 함수를 Mock Object를 통해서 테스트 해본다.

internal virtual void Synchronize(double time, bool isSeek)
{
SynchronizeData synchronizeData = GetSynchronizeData(time);
currentSlide = synchronizeData.slideIndex;
currentEvent = synchronizeData.eventIndex;
if (isSeek)
{
GotoAndStop(currentSlide, currentEvent);
}
else
{
GotoAndPlay(currentSlide, currentEvent);
}
}

위 함수에서 사용하는 클래스 멤버 함수인 GetSynchronizeData, GotoAndStop, GotoAndPlay를 Mock Object를 통해 구현하자.

1. TestCase에는 time이 15와 30이 들어온다고 가정하고, 각각의 time에  대한 Data를 미리 준비한다.
2. Mock Object를 이용해 GeySynchronizeData의 인자로 15와 30이 들어왔을 경우에 준비한 Data를 Return.
3. Mock Object를 이용해 GotoAndPlay에 1, 1이 인자로 들어오고, 한 번만 호출되는 것을 확인
4. Mock Object를 이용해 GotoAndStop에 2, 0이 인자로 들어오고, 한 번만 호출되는 것을 확인

[TestMethod]
public void TestMethod()
{
MockRepository mocks = new MockRepository();

ContentsPlayerMain cpMain = mocks.PartialMock<ContentsPlayerMain>();

SynchronizeData data1 = new SynchronizeData();
data1.slideIndex = 1;
data1.eventIndex = 1;
SynchronizeData data2 = new SynchronizeData();
data2.slideIndex = 2;
data2.eventIndex = 0;

Expect.Call(cpMain.GetSynchronizeData(15)).Return(data1);
Expect.Call(cpMain.GetSynchronizeData(30)).Return(data2);
Expect.Call(delegate { cpMain.GotoAndPlay(1, 1); }).Repeat.Once();
Expect.Call(delegate { cpMain.GotoAndStop(2, 0); }).Repeat.Once();

mocks.ReplayAll();

cpMain.Synchronize(15, false);
Assert.AreEqual(1, cpMain.CurrentSlide);
Assert.AreEqual(1, cpMain.CurrentEvent);
cpMain.Synchronize(30, true);
Assert.AreEqual(2, cpMain.CurrentSlide);
Assert.AreEqual(0, cpMain.CurrentEvent);

mocks.VerifyAll();
}


'Tech > Silverlight' 카테고리의 다른 글

ImageButton 만들기  (0) 2009.06.11
Silverlight2 Unit Test  (0) 2009.05.19
DataGrid 사용법  (0) 2009.04.06
LINQ (Language Integrated Query)  (0) 2009.04.06
Posted by 알 수 없는 사용자
Tech/Silverlight2009. 3. 19. 00:52
참고 자료 _ Loading Dynamic XAPs and Assemblies

1. What is Assembly?
2. XAP를 다운로드 하기
3. XAP에서 AppManifest.xaml 추출해 내기
4. AppManifest에 정의된 Assembly를 로드하기
5. 로드된 어셈블리에 있는 UserControl 생성하기


1. What is Assembly?


In the Microsoft .NET framework, an assembly is a partially compiled code library for use in deployment, versioning and security

Assembly는 다음과 같은 특징을 가진다.

1. 어셈블리는 코드들의 논리적인 묶음이다.
2. 어셈블리는 물리적으로 DLL또는 EXE로 존재한다.
3. 한 개의 어셈블리는 한 개이상의 파일을 포함할 수 있다.


2. XAP를 다운로드 하기

Silverlight 어플리케이션 내에서 미리 컴파일된 Silverlight Application(.xap)을 불러들이기 위해서는 WebClient를 사용한다. 불러들인 결과물의 타입은 Stream이다.

WebClient c = new WebClient();
c.OpenReadCompleted += new OpenReadCompletedEventHandler(c_OpenReadCompleted);
c.OpenReadAsync(new Uri("DynamicXAPDataGrid.xap", UriKind.Relative));

void c_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
// e.Result를 통해 xap의 Stream을 사용할 수 있다.
}

참고 사항
Silverlight 기반 응용 프로그램을 빌드하면 XAP가 만들어 진다. XAP 파일은 응용 프로그램을 시작하는데 필요한 모든 파일을 포함하는 압축된 ZIP 파일이다.

XAP 파일에는 다음과 같은 파일이 들어 있다.

1. 패키지된 어셈블리 및 응용 프로그램 진입점을 식별하는 AppManifest.xaml 파일 한 개 
2. 응용 프로그램 클래스가 들어 있는 응용 프로그램 어셈블리 한 개 
3. 0개 이상의 라이브러리 어셈블리 
4. 이미지나 비디오 파일 같은 느슨한 리소스 파일 0개 이상 


3. XAP에서 AppManifest.xaml 추출하기 

XAP 파일의 Stream에서 AppManifest.xaml 파일의 내용을 추출하기 위해서는 Application.GetResourceStream을 사용한다. GetResourceStream을 사용하면 지정한 zip 패키지에서 특정한 리소스 파일을 얻을 수 있다. (얻을 수 있는 값은 StreamResourceInfo 타입이다.)

Application.GetResourceStream(new StreamResourceInfo(e.Result, null), new Uri("AppManifest.xaml", UriKind.Relative))

AppManifest.xaml 파일의 StreamResourceInfo를 얻었다면 그 파일의 Stream을 XML 파싱을 위해 String 형태로 변환한다.

string appManifest = new StreamReader(appManifestStreamInfo.Stream).ReadToEnd();

그리고 얻어낸 string을 System.xml.Linq를 이용해 파싱하여 AssemblyPart 부분을 List로 만들어 둔다.

XElement deploy = XDocument.Parse(appManifest).Root;
List<XElement> parts = (from assemblyParts in deploy.Elements().Elements()
select assemblyParts).ToList();

제 사용한 DynamicXAPDataGrid.xap 파일에 포함된 AppManifest.xaml 파일의 내용은 다음과 같다. 이를 살펴보면 이 xap에 포함된 어셈블리가 무엇인지 확인할 수 있다.

<Deployment xmlns="http://schemas.microsoft.com/client/2007/deployment" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" EntryPointAssembly="DynamicXAPDataGrid" EntryPointType="DynamicXAPDataGrid.App" RuntimeVersion="2.0.31005.0">
  <Deployment.Parts>
    <AssemblyPart x:Name="DynamicXAPDataGrid" Source="DynamicXAPDataGrid.dll" />
    <AssemblyPart x:Name="System.Windows.Controls.Data" Source="System.Windows.Controls.Data.dll" />
    <AssemblyPart x:Name="System.Windows.Controls" Source="System.Windows.Controls.dll" />
    <AssemblyPart Source="ko/System.Windows.Controls.resources.dll" />
    <AssemblyPart Source="ko/System.Windows.Controls.Data.resources.dll" />
  </Deployment.Parts>
</Deployment>


4. AppManifest에 정의된 Assembly를 로드하기

불러들인 Silverlight 어플리케이션을 사용하기 위해서는, XAML 파일에 정의된 Assembly 파일들을 모두 로드해줘야 한다. AppManifest.xaml에서 얻어 둔 Assembly 들의 경로를 참조하여 로드한다. XAP에 포함된 어셈블리를 로드하기 위해서는 AssemblyPart 클래스를 사용한다.

Assembly asm = null;
foreach (XElement xe in parts)
{
string source = xe.Attribute("Source").Value;
AssemblyPart asmPart = new AssemblyPart();
StreamResourceInfo streamInfo = Application.GetResourceStream(
new StreamResourceInfo(e.Result, "application/binary"), new Uri(source, UriKind.Relative));
if (source == "DynamicXAPDataGrid.dll")
{
asm = asmPart.Load(streamInfo.Stream);
}
else
{
asmPart.Load(streamInfo.Stream);
}
}

AssemblyPart들 중에서 실제 Silverlight 어플리케이션인 DynamicXAPDataGrid.dll 파일은 로드를 실행하고 그 Assembly 객체를 변수에 담아둔다.


5. 로드된 어셈블리에 있는 UserControl 생성하기

실제 Silverlight 어플리케이션 Assembly 객체에서 CreateInstance를 호출해 어플리케이션 내에 포함된 UserControl 객체를 생성할 수 있다.

UserControl myControl = asm.CreateInstance("DynamicXAPDataGrid.Page") as UserControl;


'Tech > Silverlight' 카테고리의 다른 글

LINQ (Language Integrated Query)  (0) 2009.04.06
Silverlight with WEB  (0) 2009.03.30
USING STARTUP PARAMETERS WITH SILVERLIGHT  (0) 2009.03.18
HTML BROWSER INTEGRATION  (0) 2009.03.16
Posted by 알 수 없는 사용자