آموزش جامع XAML

ارسال شده توسط administrator
19. أوت 2010 17:00

 

 

این مقاله ویژگی های زبان XAML را توضیح و نشان می دهد چگونه می توان از آن برای نوشتن برنامه های Windows Presentation Foundation یا (WPF) استفاده کرد.

XAML چیست؟

XAML، یک زبان نشانه دار تعریفی (declarative markup language) است. این زبان، همانگونه که به مدل برنامه نویسی .NET Framework اعمال شده است، ایجاد user interface برای برنامه .NET Framework را ساده می کند. می توان عنصرهای UI قابل رویتی در مارک آپ تعریفی XAML ایجاد کرد، و سپس با استفاده از فایل های پشت کد، که از طریق تعاریف کلاس جزیی به مارک آپ ملحق شده اند، تعریف UI را از منطق زمان اجرا جدا کرد. این زبان بطور مستقیم فرایند ایجاد اشیا در مجموعه ای معین از تایپ های پشتیبان تعریف شده در اسمبلی ها ارائه می کند. این کار برعکس اکثر زبان های مارک آپ است، که معمولاً زبانی تعبیر شده و بدون چنین رابطه مستقیمی با سیستم تایپ پشتیبان هستند. XAML، یک جریان کاری (workflow) را که بخش های مستقل می توانند روی UI ومنطق برنامه، با استفاده از ابزارهای مختلف کار می کنند، فعال می کند.

فایل های XAML، وقتی بصورت متن ارائه می شوند، فایل هایی هستند که معمولاً دارای اکتنشن .xaml هستند. این فایل ها را می توان توسط هر انکدینگ XAMLیی کدگذاری (encode) کرد. اما انکدینگ UTF-8 رایج ترین است.

مثال زیر چگونگی ایجاد یک دکمه بعنوان یک UI را نشان می دهد. هدف این مثال تنها این است که نشان دهد XAML چگونه استعاره های (metaphor) رایج برنامه نویسی UI را نمایش می دهد.

<StackPanel>
<Button Content="Click Me"/>
</StackPanel>

خلاصه ای از سینتکس XAML

ابن بخش، فرم های پایه ای سینتکس XAML را توضیح می دهد، و مثالی کوتاه از markup می آورد. هدف این بخش، در اختیار گذاشتن اطلاعات کاملی در مورد هر فرم سینتکس، از قبیل چگونگی نمایش این فرم ها در سیستم تایپ پشتیبان نیست.

اگر شما آشنایی قبلی با XAML داشته باشید، اغلب موضوعات بخش های بعدی، برای شما مبتدی خواهد بود. این موضوع نتیجه یکی از اصول اولیه طراحی XAML است. این زبان مفاهیم خودش را تعریف می کند، اما این مفاهیم در زبان XAML و فرم مارک آپ کارایی دارند.

عنصرهای شی

معمولاً عنصر شی نمونه ای (instanceS) از یک type را تعریف می کند. این type در اسمبلی هایی که تایپ های پشتیبان را برای تکنولوژی ای که از XAML بعنوان زبان استفاده می کنند، تعریف می شود.

سینتکس عنصر شی همیشه با علامت < شروع می شود. و به دنبالش نام تایپی می آید که می خواهید در یک نمونه (instance) ایجاد کنید (این نام می تواند حاوی یک پیشوند باشد، پیشوند مفهومی است که بعداً توضیح داده خواهد شد). بعد از این، می توانید بصورت اختیاری اتریبیوت هایی در مورد عنصر شی تعریف کنید. برای تکمیل تگ عنصر شی، در آخرش علامت > بگذارید. در عوض می توانید از یک فرم که خودش بسته می شود و دارای هیچ محتوایی نیست استفاده کنید و این کار را می توانید باوسیله تگی با forward slash و علامت /> در ادامه اش انجام دهید. مثلاً نگاهی دوباره به مارک آپ مثال قبلی بیاندازید.

این مثال دو عنصر شی را معین می کند: <StackPanel> ( با content، و سپس تگ انتهایی)؛ و <Button .../>

( فرمی که خودش بسته می شود، با چندین اتریبیوت). عنصرهای شی StackPanel و Button هر کدام با نام کلاسی که توسط WPF و بخشی از اسمبلی های WPF تعریف شده اند، مساوی می شوند. وقتی یک تگ عنصر شی تعیین می کنید، در واقع دستورالعملی برای پردازش XAML ایجاد می کنید تا نمونه ای جدید ایجاد کنید. هر نمونه توسط فراخوانی constructor پیش فرض، هنگام parse یا load کردن تایپ اصلی ایجاد می شود.

سینتکس اتریبیوت (پراپرتی ها)

پراپرتی های شی را می توان بصورت اتریبیوت های عنصر شی تعریف کرد. اتریبیوت سینتکس، پراپرتی ای را که در اتریبیوت سینتکس، که متعاقبش علامت = می آید، تنظیم شده است، نامگذاری می کند. مقدار اتریبیوت همیشه بصورت رشته ای تعیین می شود که حاوی علامت نقل قول "" هست.

اتریبیوت سینتکس، موثرترین سینتکس تنظیمات پراپرتی است و بهترین سینتکس برای استفاده برنامه نویسانی است که در گذشته از زبان های مارک آپ استفاده کرده اند. مثلاً مارک آپ زیر دکمه ای ایجاد می کند که دارای متن قرمز و پیش زمینه آبی است که متنی که بصورت Content تعیین شده را نیز نمایش می دهد.

<Button Background="Blue" Foreground="Red" Content="This is a button"/>

 

سینتکس عنصر پراپرتی (Property Element Syntax)

اتریبیوت سینتکس برای بعضی از پراپرتی های عنصر شی قابل اعمال نیست، زیرا شی یا اطلاعات لازم برای در اختیار گذاشتن مقدار (value) را نمی توان درون علامت نقل قول و محدودیت های رشته سینتکس اتریبیوت بیان کرد. در چنین مواردی، می توان از سینتکسی که property element syntax شناخته م شود استفاده کرد.

سینتکس تگ شروع عنصر پراپرتی (property element start) عبارت است از: <typeName.propertyName>. معمولاً محتوای این تگ عنصر شی تایپی هست که پراپرتی بعنوان مقدار (value) درنظر می گیرد. بعد از تعیین محتوا، باید عنصر پراپرتی را با یک end tag تمام کنید. سینتکس end tag، عبارت است از: </typeName.propertyName>.

اگر اتریبیوت سینتکس قابل اعمال باشد، معمولا، استفاده از آن راحت تر است و مارک آپ های فشرده تر را ساپورت می کند. مثال زیر، همان پراپرتی هایی را نشان می دهد که در مثال اتریبیوت سینتکس قبلی تنظیم شده اند، اما این بار با استفاده از property element syntax پراپرتی Button تنظیم شده اند.

<Button>
<Button.Background>
<SolidColorBrush Color="Blue"/>
</Button.Background>
<Button.Foreground>
<SolidColorBrush Color="Red"/>
</Button.Foreground>
<Button.Content>
This is a button
</Button.Content>
</Button>

 

سینتکس Collection

زبان XAML حاوی بهینه سازی هایی است که مارک آپ های قابل خواندنی تری تولید می کنند. یکی از این بهینه سازی ها این است که اگر پراپرتی مشخصی، تایپ کالکشنی را بگیرد، آنگاه آیتم هایی که در مارک آپ بصورت عنصرهای child در مقدار آن پراپرتی تعریف می شوند، بخشی از آن کالکشن می شوند. در این مورد، کالکشن عنصر شی child، مقداری است که در پراپرتی کالکشن تنظیم می شود.

مثال زیر، سینتکس کالکشن تنظیم مقادیر پراپرتی GradientStops را نشان میدهند:

<LinearGradientBrush>
<LinearGradientBrush.GradientStops>
<!-- no explicit new GradientStopCollection, parser knows how to find or create -->
<GradientStop Offset="0.0" Color="Red" />
<GradientStop Offset="1.0" Color="Blue" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>

 

پراپرتی های XAML Content

XAML، ویژگی زبانی را تعریف می کند که یک کلاس توسط آن می تواند یکی از پراپرتی هایش را به پراپرتی XAML content تخصیص دهد. عنصرهای child آن عنصر شی، جهت تنظیم مقدار آن پراپرتی content، مورد استفاده قرار می گیرد. بعبارت دیگر، برای پراپرتی content می توانید هنگان تنظیم آن پراپرتی در مارک آپ XAML، یک عنصر پراپرتی را حذف کنید و یک استعاره parent/child در مارک آپ تولید کنید.

مثلاً، Border، پراپرتی کانتنت Child را تعیین می کند. با دو عنصر Border زیر بطور یکسان رفتار می شود. اولی از مزایای content property syntax بهره می برد و عنصر پراپرتی Border.Child را حذف می کند. دومی Border.Child را بدون واسطه نشان می دهد.

<Border>
<TextBox Width="300"/>
</Border>
<!--explicit equivalent-->
<Border>
<Border.Child>
<TextBox Width="300"/>
</Border.Child>
</Border>

 

مقدار XAML content property، بعنوان قانونی در زبان XAML، باید یا کلاً قبل یا کلاً بعد از هر عنصر پراپرتی دیگری روی همان عنصر شی داده شود. مثلاً مارک آپ زیر compile نمی شود:

<Button>I am a 
<Button.Background>Blue</Button.Background>
blue button</Button>

 

محتوی متنی (Text Content)

تعداد کمی از عناصر XAML می توانند بطور مستقیم متن را درون محتوایشان پردازش کنند. بمنظور فعال سازی این کار، یکی از موارد زیر باید true باشد:

  • کلاس باید یک content property تعریف کند، و آن content property باید تایپی قابل تخصیص به رشته (string) باشد (این تایپ می تواند Object باشد). مثلاً، هر ContentControl از Content بعنوان content property و تایپ Objectاش استفاد می کند.
  • تایپ باید یک تبدیل کننده تایپ تعریف کند، که در این مورد، از محتوای متنی بعنوان متن آغازی برای آن تبدیل کننده تایپ استفاده می شود. مثلاً <Brush>Blue</Brush>. این کلاس عملاً کمتر رایج است.
  • تایپ باید یک primitive شناخته شده زبان XAML باشد.
Content Properties و Collection Syntax ترکیب شده

مثال زیر را در نظر بگیرید:

<StackPanel>
<Button>First Button</Button>
<Button>Second Button</Button>
</StackPanel>

 

در اینجا، هر Button، عنصر child در StackPanel است. این مارک آپی موثر است که دو تگ زیر را به دو دلیل متفاوت حذف می کند.

Omitted StackPanel.Children property element: StackPanel از Panel مشتق می شود. Panel، Panel.Children را بعنوان پراپرتی XAML contentاش تعریف می کند.

: Omitted UIElementCollection object element پراپرتی Panel.Children، تایپ UIElementCollection را می گیرد که را پیاده سازی می کند. بر اساس قوانین XAML، تگ عنصر کالکشن را می توان برای پردازش کالکشن هایی از قبیل IList حذف کرد. (در این مورد، UIElementCollection عملاً نمی توان instantiate کرد زیرا constructor پیش فرض را expose نمی کند. بهمین دلیل است که عنصر شی UIElementCollection بصورت commented out نشان داده می شود.

 

<StackPanel>
<StackPanel.Children>
<!--<UIElementCollection>-->
<Button>First Button</Button>
<Button>Second Button</Button>
<!--</UIElementCollection>-->
</StackPanel.Children>
</StackPanel>

سینتکس اتریبیوت (رویدادها (Events))

سینتکس اتریبیوت را می توان برای اعضایی که رویداد (event)محسوب می شوند و نه پراپرتی، نیز استفاده کرد. در این مورد، نام اتریبیوت همان نام رویداد است. در پیاده سازی WPF از رویدادهای XAML، مقدار اتریبیوت، نام یک handler است که delegate رویداد را پیاده سازی می کند. مثلاً، مارک آپ زیر، یک هندلر برای رویداد Click به یک Button مه در مارک آپ ایجاد شده، تخصیص می دهد.

<Page 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ExampleNamespace.ExamplePage">
<Button Click="Button_Click" >Click Me!</Button>
</Page>

مطالب بیشتری در مورد eventها و XAML در WPF وجود دارد. مثلاً شاید فکر کنید آنچه که ClickHandler در اینجا reference می کند، چگونه نمایش داده و تعریف می شود. این موضوع در بخش های بعدی مقاله مورد بحث قرار خواهد گرفت.

Case و Whitespace در XAML

XAML، معمولاً به حروف بزرگ و گوچک حساس است. است. بمنظور resolve کردن تایپ های پشتیبان، همان قوانینی که CLR را بحروف بزرگ و کوچک حساس می کنند، WPF XAML را نیز حساس می کنند. عنصرهای شی، عنصرهای پراپرتی، و نام های اتریبیوت همگی باید با استفاده از sensitive casing،هنگام مقایسه براساس نام با تایپ اصلی در اسمبلی، یا با عضوی از یک تایپ، تعیین شوند. کلیدواژه ها و primitiveهای زبان XAML نیز به حروف کوچک و بزرگ حساس هستند valueها همیشه حساس نیستند. حساسیت در valueها، بستگی به رفتار تبدیل کننده تایپ دارد که با پراپرتی ای که value آنرا می گیرد در ارتباط است. بعنوان مثال، پراپرتی هایی که تایپ Boolean را می گیرند، می توانند مقادیر معادل true یا false را بگیرند، فقط به این دلیل که پارسر WPF برای XAML مبدل نوع داده ای رشته ای به Boolean، قبلاً اینها را بصورت معادل هایی مجاز کرده است.

پردازشگرها و serialize کننده های WPF XAML کل فضای خالی های غیر مهم را نادیده می گیرند، و هر فضای خالی مهم را نرمال می کنند. این، با رفتار پیش فرض XAML در برخورد با فضاهای خالی سازگار است. این رفتار معمولاً فقط هنگامی که رشته ها را درون پراپرتی content تعیین می کنیم، اهمیت و تاثیر دارد. به عبارتی ساده تر، XAML، فضا، linefeed، و کارکترهای تب را به فضاها تبدیل می کند، و سپس در صورتی که در انتهای هر رشته مجاور به هم فضایی پیدا کند، آنرا حفظ می کند.

اکتنش های مارک آپ

اکتنشن های مارک آپ، مفهومی در زبان XAML هستند. وقتی برای در اختیار گذاشتن مقدار سینتکس اتریبیوت بکار می رود، علامت های { و }، استفاده از اکتنشن مارک آپ را نشان می دهند. این کاربرد، پردازش XAML را به گریز از برخورد معمولی مقادیر اتریبیوت، چه بصورت رشته ای دارای حروف و چه بصورت مقداری قابل تبدیل، هدایت می کند.

رایج ترین اکتنشن های مارک آپ که در برنامه نویسی WPF مورد استفاده قرار می گیرد، Binding است، که برای عبارات data bining، و resource referenceهای StaticResource و DynamicResource بکار می روند. با استفاده از اکستنشن های مارک آپ می توان از سینتکس اتریبیوت برای فراهم کردن value برای تهیه مقادیر پراپرتی استفاده کرد، حتی اگر آن پراپرتی بطور کلی attribute syntax ساپورت نکند. اکستنشن های مارک آپ اغلب از تایپ های عبارت متوسط برای فعال کردن ویژگی هایی از قبیل به تاخیر انداختن مقادیر یا reference کردن اشیای دیگر که فقط هنگان اجرا حاضر هستند، استفاده می کنند.

مثلاً، مارک آپ زیر مقدار پراپرتی Style را با استفده از attribute syntax تنظیم می کند. این پراپرتی، نمونه ای از کلاس Style را می گیرد، که بطور پیش فرض نمی تواند با یک رشته سینتکس اتریبیوت، instantiate شود. اما در این مورد، اتریبیوت، اکتنشن مارک آپ مشخصی، یعنی StaticResource را reference می کند. وقتی آن اکتنشن مارک آپ پردازش می شود، ریفرنسی را به استایلی که قبلاً بصورت منبعی key شده در منبع لغت نامه instantiate شده را باز می گرداند.

<Page.Resources>
<SolidColorBrush x:Key="MyBrush" Color="Gold"/>
<Style TargetType="Border" x:Key="PageBackground">
<Setter Property="Background" Value="Blue"/>
</Style>


...


</Page.Resources>
<StackPanel>
<Border Style="{StaticResource PageBackground}">


...


</Border>
</StackPanel>

تبدیل کننده های تایپ (Type Converters)

در بخش قبلی گفته شد که مقدار اتریبیوت باید بتواند توسط یک رشته تنظیم شود. مدیریت پایه ای چگونگی تبدیل رشته ها به دیگر تایپ های شی یا مقادیر ابتدایی، بر پایه خود تایپ String است، بعلاوه پردازش ذاتی بعضی از تایپ ها از قبیل DateTime یا Uri. اما خیلی از تایپ ها یا اعضای WPF این تایپ ها، رفتار پردازش اتریبیوت رشته را توسعه می دهند، بطوری که نمون هایی از تایپ های شی پیچیده تر را می توان بصورت رشته یا اتریبیوت تعیین کرد.

ساختار Thickness، مثالی از تایپی است که دارای مبدل تایپ است که برای صفحات XAML فعال شده است. Thickness، اندازه گیری های درون یک مستطیل nest شده را نمایش می دهد و بعنوان مقدار برای پراپرتی هایی از قبیل Margin بکار می رود. با قرار دادن مبدل تایپ روی Thickness، همه پراپرتی هایی که از یک Thickness استفاده می کنند، راحت تر تعیین می شوند، زیرا می توان آنها را بصورت اتریبیوت تعیین کرد. مثال زیر، از مبدل تایپ و سینتکس اتریبیوت برای تهیه مقدار برای Margin استفاده میکند:

<Button Margin="10,20,10,30" Content="Click me"/>

مثال attribute syntax قبلی، معادل مثال سینتکس طولانی زیر است، ولی در عوض، Margin از طریق سینتکس عنصر پراپرتی تنظیم می شود که حاوی عنصر شی Thickness است. پراپرتی های چهار دکمه Thickness، روی نمونه جدید بصورت اتریبیوت تنظیم می شوند:

<Button Content="Click me">
<Button.Margin>
<Thickness Left="10" Top="20" Right="10" Bottom="30"/>
</Button.Margin>
</Button>

نکته:

همچنین تعداد محدودی شی وجود دارد که تبدیل تایپ تنها راه رایج برای تنظیم پراپرتی به آن تایپ بدون درگیر کردن یک زیر کلاس است، زیرا خود تایپ دارای constructor پیش فرض نیست. Cursor، مثالی از این دست است.

عنصرهای ریشه XAML و فضاهای نامی XAML

برای اینکه یک فایل XAML هم دارای شکل خوب باشد و هم فایلی معتبر باشد، فقط یک عنصر باید داشته باشد. در سناریوهای معمولی WPF، از یک فایل ریشه ای استفاده می شود که معنی برجسته ای در مدل برنامه WPF باشد ( مثلاً Windows یا Page برای صفحه، ResourceDictionary برای دیکشنری خارجی، یا Application برای تعریف برنامه). مثال زیر، عنصر ریشه فایل معمولی XAML برای صفحه WPF را با عنصر ریشه Page نشان می دهد.

<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"


...


&lt;/Page>

همچنین عنصر ریشه حاوی اتریبیوت های xmlns و xmlns:x. است. این اتریبیوت ها به پردازشگر XAML نشان می دهد کدام فضاهای نامی XAML حاوی تعاریف تایپ برای تایپ های پشتیبانی هستند که مارک آپ آنها را بصورت عنصر ریفرنس می کند. اتریبیوت xmlns بطور معین فضای نامی پیش فرض XAML رانشان می دهد. درون فضای نامی XAML، می توان عناصر شی در مارک آپ را بدون پیشوند تعیین کرد. در اکثر سناریوهای برنامه WPF، و تقریباً همه مثال ها ارائه شده در بخش های دبلیو پی اف SDK، فضای نامی پیش فرض XAML به فضای نامی http://schemas.microsoft.com/winfx/2006/xaml/presentation، مپ (map) می شود. اتریبیوت xmlns:x، فضای نامی اضافی ای نشان می دهد که فضای نامی زبان XAML زیر را مپ می کند:

http://schemas.microsoft.com/winfx/2006/xaml

استفاده از xmlns برای تعریف اسکوپ برای استفاده و مپینگ فضای نامی، با XML 1.0 specification سازگار است. تفاوت اسکوپ های نامی XAML با اسکوپ های نامی XML در این است که اسکوپ نامی XAML در مورد اینکه چگونه عنصرهای اسکوپ نامی توسط تایپ ها هنگامی که به type resolution و پارسینگ XAML می رسد، چیز جدیدی استدلال می کند.

توجه کنید که اتریبیوت های xmlns فقط برای عنصر ریشه هر فایل XAML ضروری هستند. تعاریف xmlns به تمامی عنصرهای نزولی (descendant) عنصر ریشه اعمال می شوند (این رفتار نیز با XML 1.0 specification برای xmlns سازگار است). این اتریبیوت ها در عنصرهای دیگر زیرریشه نیز مجاز هستند، و به هر عنصر نزولی عنصر تعریف کننده اعمال می شوند. اما تعریف یا بازتعریف عادی فضاهای نامی XAML ممکن است به استایل مارک آپ XAML، که خواندنش مشکل است، منجر شود.

پیاده سازی WPF از پردازشگر XAMLاش حاوی زیربنایی است که از اسمبلی های هسته ای WPF آگاه است. اسمبلی های هسته ای WPF، برای بعضی از تایپ هایی که مپینگ های WPF به فضای نامی پیش فرض XAML را ساپورت می کنند، شناخته شده هستند. این کار از طریق پیکربندی ای که بخشی از فایل ساخت پروژه تان و ساخت WPF و سیستم های پروژه تان است انجام می شود. بنابراین، تعریف فضای نامی پیش فرض XAML مانند xmlns پیش فرض، تنها چیزی است برای ریفرنس کردن عنصرهایی که از اسمبلی های WPF می آیند نیاز دارید.

پیشوند x:

در مثال قبلی از عنصر ریشه، از پیشوند x: برای مپ کردن فضای نامی http://schemas.microsoft.com/winfx/2006/xaml استفاده شد، که فضای نامی اختصاصی XAML است که constructهای زبان XAML را ساپورت می کند. از این پیشوند برای مپ کردن فضای نامی XAML در templateهای پروژه ها، مثال ها، و مستند سازی (documentation) در سراسر این SDK استفاده می شود. فضای نامی XAML برای زبان XAML حاوی چندین construct برنامه نویسی است که کاربرد زیادی دارد. در زیر لیستی از رایج ترین constructهای برنامه نویسی با پیشوند x: آورده شده است:

x:Key: کلیدی مخصوص برای هر ریسورس در ResourceDictionary (یا هرمفهوم دیکشنری شبیه در frameworkهای دیگر) ایجاد می کند. احتمالاً این کلید %90 استفاده از x: را که در مارک آپ برنامه های WPF می بینید به خود اختصاص می دهد.

x:Class: فضای نامی CLR و نام کلاس را برای کلاسی که کد پشتی (code-behind) را برای صفحه در اختیار می گذارد، تعیین می کند. شما باید چنین کلاسی برای ساپورت کد پشتی برای هر مدل برنامه نویسی WPF داشته باشید، و بنابراین همیشه x: را باید بصورت مپ شده ببینید، حتی اگر هیچ ریسورسی وجود نداشته باشد.

x:Name: نام شی زمان اجرا را برای مثالی که در کد زمان اجرا، بعد از اینکه شی عنصر پردازش شد، وجود دارد تعیین می کند. بطور کلی باید از پراپرتی معادل که در WPF برای x:Name: تعریف شده است استفاده کنید. چنین پراپرتی هایی به پراپرتی پشتیبان CLR مپ می شوند و در نتیجه برای برنامه نویسی مناسب تر هستند، که شما در آن معمولاً از کد زمان اجرا استفاده می کنید تا عنصرهای نام دار را از XAML آغاز شده پیدا کند. رایج تین پراپرتی از این دست، FrameworkElement.Name است. ممکن است هنگامی که پراپرتی Name در یک تایپ ویژه ساپورت نمی شود، هنوز از x:Name استفاده کنید. این کار در بعضی از سناریوهای انیمیشن اتفاق می افتد.

x:Static: ریفرنسی را فعال می کند که یک valueی ایستاتیک را که پراپرتی سازگار با XAML نیست را بازمی گرداند.

x:Type: ریفرنسی را بر اساس نام تایپ می سازد. از این برای تعیین اتریبیوت هایی که type را می گیرند استفاده می شود، از قبیل Style.TargetType، گرچه این پراپرتی اغلب دارای تبدیل string به Type است بطوریکه استفاده از اکستنشن مارک آپ x:Type اختیاری است.

constructهای برنامه نویسی دیگری هم در فضای نامی x: prefix/XAML وجود دارند که خیلی رایج نیستند.

پیشوندها و تایپ های سفارشی

برای اسمبلی های سفارشی خودتان، یا اسمبلی هایی خارج از هسته PresentationCore، PresentationFramework، و WindowsBase در WPF، می توانید اسمبلی را بعنوان مپینگ سفارشی xmlns تعیین کرد. سپس می توانید تا وقتی که آن تایپ بطور صحیح برای ساپورت کاربردهای XAML پیاده سازی می شموند، تایپ هایی را از اسمبل ای که خودتان وجود دارد، ریفرنس کنید.

مثال زیر، مثالی بسیار ساده از چگونگی کارکردن پیشوندها در مارک آپ XAML است. پیشوند سفارشی در تگ عنصر ریشه تعریف می شود، و به اسمبلی ای که پکیچ می شود و با application قابل دسترسی است، مپ می شود. این اسمبلی حاوی تایپ NumericUpDown است، که برای ساپورت کاربرد عمومی XAML و همچنین استفاده از وراثت کلاس پیاده سازی می شود. نمونه ای از این کنترل NumericUpDown، بصورت عنصر شی تعریف می شود.

<Page
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:custom="clr-namespace:NumericUpDownCustomControl;assembly=CustomLibrary"
>
<StackPanel Name="LayoutRoot">
<custom:NumericUpDown Name="numericCtrl1" Width="100" Height="60"/>
...
</StackPanel>
</Page>

رویدادها و کد پشتی XAML

اکثر برنامه های WPF هم حاوی مارک آپ XAML و هم کد پشتی است. در یک پروژه، XAML بصورت فایل .xaml نوشته می شود، و از یک زبان CLR از قبیل Microsoft Visual Basic یا C# برای نوشتن فایل کد پشتی استفاده می شود. وقتی یک فایل XAML بعنوان بخشی از برنامه نویسی WPF و مدل های application، کمپایل می شود، موقعیت فایل کد پشتی XAML از طریق تعیین فضای نامی و کلاسی بعنوان اتریبیوت عنصر ریشه XAML شناسایی می شود.

در مثال هایی که تا آلان آورده شده، چندین دکمه دیده اید، ولی هیچ کدام از این دکمه ها رفتار منطقی ای که مربوط به آنها باشد ندارند. مکانیزم ابتدایی در سطح application برای اضافه کردن رفتار به عنصر شی، استفاده از یک رویداد (event) موجود در کلاس عنصر و نوشتن یک handler برای آن رویداد است.

<Page 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ExampleNamespace.ExamplePage">
<Button Click="Button_Click" >Click Me!</Button>
</Page>


Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
Dim b As Button = e.Source
b.Foreground = Brushes.Red
End Sub
دقت کنید که فایل code-behind از فضاهای نامی ExampleNamespace استفاده می کند و ExamplePage را بعنوان کلاسی جزیی درون آن فضای نامی تعریف می کند. کمپایلر مارک آپ WPF، با مشتق کردن کلاسی از تایپ عنصر ریشه، کلاسی جزیی برای فایل XAML کمپایل شده ایجاد شد. وقتی کد پشتی ای ایجاد می کنید که همان کلاس جزیی را نیز تعریف می کند، کد خروجی در همان فضای نامی و کلاس application کمپایل شده ترکیب می شود.

عنصرهای نام دار XAML

بطور پیش فرض، نمونه شی ای که از طریق پردازش عنصر شی XAML در گراف شی ایجاد می شود، دارای identifier منحصر بفرد یا ریفرنس شی نیست. در مقابل، اگر کانستراکتوری را در در فرابخوانید، تفریباً همیشه از نتیجه کانستراکتور برای قراردادن متغیری برای نمونه ساخت شده استفاده می کنید، بطوریکه بعداً می توانید نمونه را در کدتان ریفرنس کنید. برای فراهم کردن دسترسی استاندارد به شی ای که از طریق تعریف مارک آپ ایجاد شده، XAML اتریبیوت x:Name را تعریف می کند. می توانید مقدار اتریبویت x:Name را روی هر عنصر شی تنظیم کنید. در کد پشتی تان، Identifier انتخابی شما، معادل متغیر نمونه ایست که به نمونه ساخته شده refer میزشود.

عنصرهای XAML در سطح قالب کاری WPF، پراپرتی Name را به ارث می برند، که معادل اتریبیوت x:Name تعریف شده XAML است. بعضی کلاس های دیگر، معادل های در سطح پراپرتی برای x:Name فراهم می کنند که عموماً بصورت پراپرتی Name تعریف می شوند. اگر نتوانید پراپرتی Name را در جدول اعضای تایپ یا عنصر منتخب تان پیدا کنید، در عوض می توانید از x:Name استفاده کنید. مقدارهای x:Name، یک identifier برای عنصر XAML که می توان هنگام اجرا استفاده کرد، فراهم می کند.

مثال زیر، یک Name روی عنصر StackPanel تنظیم می کند. سپس یک Buttonدرون آن StackPanel، آن را از طریق ریفرنس نمونه اش یعنی buttonContainer، همانگونه که توسط Name تنظیم شده، ریفرنس می کند.


 

 

 

 

 

 

 

<StackPanel Name="buttonContainer">


...


<Button Click="RemoveThis">Click to remove this button</Button>
</StackPanel>

 

درست مثل یک متغیر، نام XAML برای نمونه توسط مفهوم scope مدیریت می شود، بطوریکه نام ها را می توان درون اسکوپی که قابل پیش بینی است، تحمیل کرد تا منحصر بفرد باشند. مارک آپ ابتدایی که صفحه را تعریف می کند، اسکوپ نامی منحصربفردی را با مرز اسکوپ نامی XAML که عنصر ریشه آن صفحه است، اهدا می کند.ُ اما دیگر منابع مارک آپ می توانند با صفحه ای هنگام اجرا تعامل داشته باشند.

پراپرتی ها و رویدادهای الصاق شده

XAML، ویژگی ای از زبان را تعیین می کند که بعضی از پراپرتی ها یا رویدادها را قادر به شناخته شدن روی هر عنصری می کند، بدون توجه به اینکه آیا آن پراپرتی یا رویداد در تعاریف تایپ برای عنصری که رویش تنظیم شده وجود دارد یا خیر. ورژن پراپرتی های این ویژگی، پراپرتی الصاق شده (attached property)، و ورژن رویداد های این ویژگی، رویداد الصاق شده (attached event) نامیده می شود. می توان پراپرتی ها و رویدادهای الصاق شده را اعضای جهانی در نظر گرفت که روی هر نمونه عنصر یا شی XAML تنظیم می شوند. اما آن کلاس یا عنصر یا زیربنای بزرگتر باید پراپرتی پشتیبان را برای مقادیر الصاق شده ساپورت کند.

پراپرتی های الصاق شده در XAML معمولاً توسط سینتکس اتریبیوت مورد استفاده قرار می گیرند. در سینتکس اتریبیوت، باید یک پراپرتی الصاق شده در فرم ownerType.propertyName تعیین کنید.

رایج ترین سناریو برای پراپرتی های الصاق شده، فعال کردن عنصرهای child برای گزارش کردن مقدار پراپرتی به عنصر parent است.

مثال زیر، پراپرتی الصاق شده DockPanel.Dock را نشان می دهد. کلاس DockPanel، اکسسورهای DockPanel.Dock را تعریف می کند، و بنابراین مالک پراپرتی الصاق شده محسوب می شود. همچنین کلاس DockPanel، حاوی منطقی است که عنصرهای child را تکرار می کند و هر عنصر را برای مجموعه ای از مقدارهای DockPanel.Dock چک می کند. اگر valueیی پیدا شود، آن مقدار (value) هنگام layout برای موقعیت یابی عنصرهای child مورد استفاده قرار می گیرد. استفاده از پراپرتی الصاق شده DockPanel.Dock و قابلیت موقعیت یابی در حقیقت به سناریوی کلاس DockPanel انگیزه می دهد.

<DockPanel>
<Button DockPanel.Dock="Left" Width="100" Height="20">I am on the left</Button>
<Button DockPanel.Dock="Right" Width="100" Height="20">I am on the right</Button>
</DockPanel>

در WPF، اکثر یا همه پراپرتی های الصاق شده به صورت پراپرتی های مستقل نیز پیاده سازی می شوند.

رویدادهای الصاق شده نیز از فرم سینتکس اتریبیوت ownerType.eventName استفاده می کنند. درست مثل رویدادهای غیر الصاقی، مقدار اتریبیوت رویداد الصاق شده در XAML، نام متد هندلر را تعیین می کند. کاربرد رویداد الصاق شده در WPF XAML کمتر رایج است.

تایپ های پایه و XAML

WPF XAML پایه و فضای نامی XAML، مجموعه ای از تایپ هایی است که با اشیا CLR و عنصرهای مارک آپ XAML تطابق دارد. اما همه کلاس ها را نمی توان به عنصرها مپ کرد. از کلاس های انتزاعی مانند ButtonBase، و بعضی کلاس های غیرانتزاعی پایه برای وراثت در مدل اشیای CLR استفاده می شود. کلاس های پایه، شامل کلاس های انتزاعی هنوز برای توسعه XAML مهم هستند زیرا هر کدام از عنصرهای XAML واقعی، اعضایی را از بعضی کلاس های پایه در سلسله مراتبشان به ارث می برند. این اعضا اغلب حاوی پراپرتی هایی هستند که می توان بصورت اتریبیوت هایی روی عنصر یا رویدادهایی که می توان مدیریت کرد، تنظیم کرد. FrameworkElement، پایه واقعی کلاس UI در WPF در سطح قالب کاری WPF است. هنگام طراحی UI، باید از شکل، پنل، دکوراتور، یا کلاس های کنترل، که همگی از FrameworkElement مشتق می شوند، استفاده کنید. کلاس FrameworkContentElement، عنصرهای سند گرا را ساپورت می کند. این عنصرها در flow layout presentation، با استفاده از APIهایی که APIهای موجود در FrameworkElement را mirror می کنند، خوب کار می کنند. ترکیب اتریبیوت های در سطح عنصر و مدل شی CLR، مجموعه ای از پراپرتی های رایج را در اختیار شما قرار می دهد که در اکثر عنصرهای واقعی XAML، قابل تنظیم هستند.

امنیت XAML

XAML زبانی markup است که مستقیماً instantiation و execution شی را نمایش می دهد. بنابراین، عناصر ایجاد شده در XAML دارای قابلیتی یکسان برای تعامل با ریسورس های سیستم هستند.

WPF، از .NET Framework 4 security framework Code Access Security یا (CAS) ساپورت می کند. این بدین معناست که محتویات در حال اجرای WPF در اینترنت، permissionهای اجرا (execution) را کاهش داده است. "Loose XAML" (صفحه های کمپایل نشده XAML که زمان بارگذاری توسط یک XAML viewer تفسیر می شود)، و برنامه مرورگر XAML، معمولاً در ناحیه اینترنت اجرا می شوند و همچنان از همان مجموعه permissionها استفاده می کنند. اما، XAMLیی که در برنامه ای کاملاً مطمئن بارگذاری شده است، مانند برنامه های میزبان، همان دسترسی به ریسورس های سیستم را دارد.

بارگذاری XAML از کد

از XAML می توان برای تعریف همه UIها استفاده کرد. اما گاهی اوقات برای تعریف تنها بخشی از UI در XAML نیز مناسب است. از این قابلیت می توان برای فعال کردن سفارشی کردن جزیی، ذخیره محلی اطلاعات، استفاده از XAML برای فراهم کردن شی تجارت، یا سناریوهای ممکن دیگر استفاده کرد. کلید این سناریوها، کلاس XamlReade و متد Load است. ورودی (input)، یک فایل XAML، و خروجی (output)، شی ای است که کل tree زمان اجرای شی ای را که از آن مارک آپ ایجاد شده، نمایش می دهد. سپس می توانید شی را insert کنید تا پراپرتی شی دیگری باشد که از قبل در application وجود دارد. تا وقتی که پراپرتی، یک پراپرتی مناسب در مدل محتوایی باشد که قابلیت نمایش نهایی را دارد، و موتور اجرایی (execution engine) را مطلع می کند که محتوای جدیدی به برنامه اضافه شده است، می توانید محتوای در حال اجرای برنامه را به سادگی و از طریق بارگذاری در XAML اصلاح کنید. توجه داشته باشید که این قابلیت، بدلیل تاثیرات واضح امنیتی بارگذاری فایل ها در برنامه، هنگام اجرا، معمولاً فقط در برنامه های کاملاً مطمئن دردسترس است.

تگ ها:

دسته بندی ها: مقالات آموزش WCF | مقالات آموزشی XAML

Windows Communication Foundation چیست؟

ارسال شده توسط administrator
1. جوييه 2010 06:44

 

Windows Communication Foundation یا (WCF)، یک قالب کاری بر ای ساختن برنامه های سرویس گرا است. با استفاده از WCF می توانید داده ها را به صورت پیام هایی از یک درگاه سرویس به درگاهی دیگر ارسال کند. یک درگاه سرویس (service endpoint) می تواند بخشی از سرویس همیشه در دسترسی باشد که توسط IIS، میزبانی می شود، یا می تواند سرویسی باشد که توسط یک برنامه میزبانی می شود. یک درگاه می تواند client یک سرویس باشد که داده ها را از درگاه سرویس request می کند. پیام ها می توانند به سادگی یک کاراکتر واحد یا یک کلمه باشند که به صورت XML ارسال شده است. یا به پیچیدگی یک رشته از داده های binary. چند سناریوی نمونه شامل موارد زیر می شود:

  • یک سرویس امن برای مبادلات تجاری
  • سرویسی که داده های کنونی را برای دیگران مهیا می کند، از قبیل گزارش ترافیک یا دیگر سرویس های مانیتورینگ.
  • یک سرویس چت که به دو نفر اجازه می دهد با هم در ارتباط باشند یا داده ها را به هم رد و بدل کنند.
  • یک برنامه dashboard که داده های یک یا چندین برنامه را جمع آوری می کند و در یک presentation منطقی نمایش می دهد.
  • Expose کردن یک workflow پیاده سازی شده با استفاده از Windows Workflow Foundation به صورت یک سرویس WCF.
  • یک برنامه Silverlight برای جمع آوری آخرین فیدهای داده ها.

در حالی که ایجاد چنین برنامه هایی قبل از وجود WCF ممکن بود، WCF توسعه درگاه ها را از قبل آسانتر می کند. به طور خلاصه، WCF جهت ارائه روشی قابل مدیریت برای ایجاد سرویس های وب و clientهای سرویس وب، طراحی شده است.

ویژگی های WCF

WCF شامل مجموعه ویژگی های زیر است.

  • گرایش به سرویس

یکی از نتایج استفاده از استانداردهای WS این است که WCF شما را قادر به ایجاد برنامه های سرویس گرا می کند. معماری های سرویس گرا (SOA) ،به معنای وابستگی به وب سرویس ها جهت ارسال و دریافت داده ها است. این سرویس ها مزیت loosely-coupled بودن بجای hard-coded بودن از برنامه ای به برنامه دیگر هستند. یک رابطه loosely-coupled بدین معناست که هر client ایجاد شده در هر plaftorm می تواند تا وقتی که contractهای لازم برآورده می شوند، به هر سرویسی وصل شود.

  • Interoperability

WCF، استانداردهای صنعتی مدرن را برای interoperability سرویس های وب پیاده می کند.

  • الگوهای پیام چندگانه

پیام ها با استفاده یکی از چندین الگو مبادله می شوند. یکی از رایج ترین الگوها، الگوی request/reply است، که یک درگاه داده ها را از یک درگاه دیگر request می کند، و آن درگاه پاسخ می دهد. الگوهای دیگری نیز وجود دارند، مانند یک پیام یک طرفه (one-way) که در آن یک درگاه واحد پیامی را بدون درخواست پاسخ ارسال می کند. الگویی پیچیده تر، الگوی تبادل دوگانه است که دو درگاه یک connection یرقرار می کنند و داده ها را ردوبدل می کنند، مانند یک برنامه پیام نگاری سریع.

  • Service Metadata

WCF، با استفاده از فرمت های معین شده در استانداردهای صنعتی از قبیل WSDL، XML Schema و WS-Policy، انتشار service metadata را ساپورت می کند. می توان از این metadata، بر ای پیکربندی و generate کردن اتوماتیک client بمنظور دسترسی به سرویس های metadata استفاده کرد. می توان metadata را با استفاده از استاندارد Web Service Metadata Exchange در HTTP یا HTTPS منتشر کرد.

  • Data Contracts

از آنجاییکه WCF با استفاده از .NET Framework ساخته شده است، متدهای code-friendly برای تامین contractهایی که می خواهید اجرا کنید را نیز در بر می گیرد. یکی از انواع جهانی contractها، data contract است. در واقع، هنگامی که سرویس تان را با استفاده از Visual C# یا Visual Basic کد نویسی می کنید، اسانترین راه یرای مدیریت داده ها، ایجاد کلاس هایی است که موجودیت داده ها را با propertyهایی که به موجودیت داده ها تعلق دارند، نمایش می دهند. WCF شامل یک سیستم جامع برای کارکردن با داده ها به روشی آسانتر است. بعد از اینکه کلاس هایی را که داده ها را نمایش می دهند، وارد کردید، سرویس شما به طور اتوماتیک metadata را generate می کند.

  • امنیت

می توان پیام ها را برای محافظت از حریم خصوصی رمزگذاری کرد و می توان کاربران را ملزم کرد قبل از مجاز شدن به دریافت پیا ها، خودشان را authenticate کنند. امنیت را می توان با استفاده از استانداردهای شناخته شده از قبیل SSL یا WS-SecureConversation پیاده سازی کرد.

  • Transportها و Encodingهای چندگانه

پیام ها را می توان با هریک از چندین پروتکل و رمزگذاری transport داخلی ارسال کرد. رایج ترین پروتکل و رمزگذاری، ارسال پیام های SOAP متنی رمزگذاری شده با استفاده از HTTP برای استفاده در WWW است. متناوباً، WCF به شما اجازه ارسال پیام ها در TCP، یا MSMQ را می دهد. این پیام ها را می توان به صورت متن یا با استفاده از یک فرمت binary بهینه شده، رمزگذاری کرد. داده ها binary را می توان با استفاده از استاندارد MTOM به طور موثری ارسال کرد. اگر هیچ یک از transportها یا encodingهای موجود، نیاز شما را برآورده نکنند، می توانید transport یا encodingهای دلخواه خودتان را ایجاد کنید.

  • پیام های قابل اعتماد و به صف شده (queued)

WCF با استفاده از sessionهای پیاده شده روی WS-Reliable Messaging، پیام های قابل اعتماد را ساپورت می کند.

  • پیام های مدت دار (Durable)

پیام مدت دار، پیامی است که در صورت وقوع اختلال در ارتباط، هرگز از دست نمی رود. پیام ها در الگوی پیام مدت دار، همیشه در database ذخیره می شوند. اگر اختلالی روی دهد، database به شما اجازه می دهد هنگامی که connection به حالت اول بازمی گردد، به تبادل پیام ادامه دهید. همچنین می توانید با استفاده ازWorkflow Foundation ، یک پیام مدت دار ایجاد کنید.

  • تراکنش ها

WCF، تراکنش ها را هم با استفاده از یکی از این سه مدل تراکنش ساپورت می کند: AtomicTtransactions، APIها در فضای نامی System.Transactions، و Microsoft Distributed Transaction Coordinator.

  • Ajax و ساپورت Rest

REST، نمونه ای از تکنولوژی وب 2 در حال تکامل است. می توان WCF را برای پردازش داده های XML ساده پیکربندی کرد. همچنین می توان WCF را برای ساپورت از فرمتهای خاص XML از قبیل ATOM، که یک استاندارد محبوب RSS است، و حتی فرمت های غیر XML از قبیل JavaScript Object Notation، گسترش داد.

  • توسعه پذیری (Extensibility)

معماری WCF دارای چندین نکته توسعه پذیری است. اگر نیاز به قابلیت اضافی باشد، نکاتی وجود دارند که به شما اجازه سفارشی کردن رفتار یک سرویس را می دهند.

ادغام WCF با دیگر تکنولوژی های مایکروسافت

WCF یک platform قابل انعطاف است. به علت وجود این انعطاف پذیری، WCF در چندین محصول دیگر مایکروسافت نیز قابل استفاده است. اولین تکنولوژی که با WCF شریک شد، Windows Workflow Foundation یا (WF) بود. Workflow، توسعه برنامه را از طریق کپسوله کردن مراحل در workflow به صورت "activities"، ساده می کند. در نسخه اول Windows Workflow Foundation، برنامه نویس مجبور بود یک هاست برای workflow ایجاد کند. نسخه بعدی Windows Workflow Foundation با WCF ادغام شد. این کار به هر workflow اجازه می داد براحتی در سرویس WCF ذخیره شود؛ می توان این کار را با انتخاب اتوماتیک WF/WCF بعنوان یک project type در Visual Studio 2010 انجام داد.

همچنین Microsoft BizTalk Server R2 از WCF به عنوان یک تکنولوژی برای برقراری ارتباط استفاده می کند. BizTalk جهت دریافت و انتقال داده ها از یک فرمت استاندارد به فرمتی دیگر طراحی شده است. پیام ها باید به box مرکزی پیام ها یعنی جاییکه می توان با استفاد ه از یک مپینگ دقیق یا یکی از ویژگی های BizTalk، از قبیل موتور workflow، پیام ها را منتقل کرد. BizTalk الان از آداپتور WCF Line of Business یا (LOB) جهت تحویل پیام ها به box پیام استفاده می کند.

Microsoft Silverlight، یک platform برای ایجاد برنامه های وب پیشرفته و interoperable است که به برنامه نویسان اجازه می دهد وب سایتهای حساس به رسانه (media-intensive) ایجاد کنند. نسخه دوم Silverlight، WCF را به عنوان یک تکنولوژی برقراری ارتباط جهت متصل کردن برنامه های Silverlight به درگاه های WCF، ترکیب کرده است.

Microsoft .NET Services، یک برنامه محاسبه گر است که از WCF برای ساختن برنامه های تحت وب استفاده می کند. می توان از NET Services برای ایجاد سرویس های WCF استفاده کرد.

ویژگی های میزبانی سرور برنامه Windows Server AppFabric بطور ویژه ای برای نصب و مدیریت برنامه هایی که از WCF جهت برقراری ارتباط استفاده می کند، ساخته شده است. این ویژگی ها شامل ابزارهایی پیشرفته و پیکربندی آپشن هایی است که بطور ویژه برای برنامه های تحت WCF طراحی شده اند.

چگونگی استفاده از یک Windows Communication Foundation Client

ارسال شده توسط administrator
24. جوان 2010 11:32

این مقاله، آخرین مرحله از شش مرحله ای است که باید برای ایجاد یک سرویس Windows Communication Foundation یا (WCF) و یک client که سرویس را فراخوانی می کند، انجام داد.

بعد از اینکه پروکسی Windows Communication Foundation ایجاد و پیکربندی شد، می توان یک نمونه client ایجاد کرد و
client application را compile و برای رابطه با سرویس WCF استفاده کرد. این مقاله، فرآیندهای ایجاد و استفاده از یک WCF client را توضیح می د هد. این فرآیند این سه کارانجام مید هد:

  1. یک WCF client ایجاد می کند.
  2. service operationها را از پروکسی generate شده فراخوانی می کند.
  3. بعد از اینکه فراخوانی operation به اتمام رسید، client را می بندد.

کدی که در روش بحث می شود، در مثال زیر آمرده شده است. کد این مرحله باید در متد Main() کلاس generate شده در پروژه client قرا گیرد.

استفاده از یک Windows Communication Foundation Client

1. یک نمونه EndpointAddress برای آدرس پایه سرویسی که می خواهید فرابخوانید، ایجاد کنید و سپس یک WCF Client object ایجاد کنید.

در VB:

' Step 1: Create an endpoint address and an instance of the WCF Client.
Dim epAddress As New EndpointAddress
("http://localhost:8000/ServiceModelSamples/Service/CalculatorService")
Dim Client As New CalculatorClient(New WSHttpBinding(), epAddress)

 

در #C:

//Step 1: Create an endpoint address and an instance of the WCF Client.
CalculatorClient client = new CalculatorClient();

client operation .2ها را از داخل Client فرابخوانید.

 

در VB:

'Step 2: Call the service operations.
'Call the Add service operation.
Dim value1 As Double = 100D
Dim value2 As Double = 15.99D
Dim result As Double = Client.Add(value1, value2)
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result)

'Call the Subtract service operation.
value1 = 145D
value2 = 76.54D
result = Client.Subtract(value1, value2)
Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result)

'Call the Multiply service operation.
value1 = 9D
value2 = 81.25D
result = Client.Multiply(value1, value2)
Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result)

'Call the Divide service operation.
value1 = 22D
value2 = 7D
result = Client.Divide(value1, value2)
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result)

در #C:

// Step 2: Call the service operations.
// Call the Add service operation.
double value1 = 100.00D;
double value2 = 15.99D;
double result = client.Add(value1, value2);
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);

// Call the Subtract service operation.
value1 = 145.00D;
value2 = 76.54D;
result = client.Subtract(value1, value2);
Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);

// Call the Multiply service operation.
value1 = 9.00D;
value2 = 81.25D;
result = client.Multiply(value1, value2);
Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);

// Call the Divide service operation.
value1 = 22.00D;
value2 = 7.00D;
result = client.Divide(value1, value2);
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);

Close .3 را از WCF client فرابخوانید و منتظر بمانید تا کاربر enter را فشار دهد تا برنامه را terminate کند.


 

در VB:

' Step 3: Closing the client gracefully closes the connection and cleans up resources.
Client.Close()

Console.WriteLine()
Console.WriteLine("Press <ENTER> to terminate client.")
Console.ReadLine()

 

در #C:

Console.WriteLine();
Console.WriteLine("Press <ENTER> to terminate client.");
Console.ReadLine();

 

مثال

مثال زیر، چگونگی ایجاد یک WCF client و فراخوانی operationهای client، و چگونگی بستن clientرا بعد از اتمام فراخوانی opertaion نشان می دهد.

WCF client ایجاد شده و کد زیر را به یک executable بنام Client.exe، کمپایل کنید. مطمئن شوید که System.ServiceModel راهنگام کمپایل کردن کد، reference می کنید.

در VB:

Imports System
Imports System.Collections.Generic
Imports System.Text
Imports System.ServiceModel


Module Client

Sub Main()
' Step 1: Create an endpoint address and an instance of the WCF Client.
Dim epAddress As New EndpointAddress("http://localhost:8000/ServiceModelSamples/Service/CalculatorService")
Dim Client As New CalculatorClient(New WSHttpBinding(), epAddress)

'Step 2: Call the service operations.
'Call the Add service operation.
Dim value1 As Double = 100D
Dim value2 As Double = 15.99D
Dim result As Double = Client.Add(value1, value2)
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result)

'Call the Subtract service operation.
value1 = 145D
value2 = 76.54D
result = Client.Subtract(value1, value2)
Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result)

'Call the Multiply service operation.
value1 = 9D
value2 = 81.25D
result = Client.Multiply(value1, value2)
Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result)

'Call the Divide service operation.
value1 = 22D
value2 = 7D
result = Client.Divide(value1, value2)
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result)

' Step 3: Closing the client gracefully closes the connection and cleans up resources.
Client.Close()

Console.WriteLine()
Console.WriteLine("Press <ENTER> to terminate client.")
Console.ReadLine()

End Sub
End Module

 

در #C:

using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceModel;

namespace ServiceModelSamples
{

class Client
{
static void Main()
{
//Step 1: Create an endpoint address and an instance of the WCF Client.
CalculatorClient client = new CalculatorClient();


// Step 2: Call the service operations.
// Call the Add service operation.
double value1 = 100.00D;
double value2 = 15.99D;
double result = client.Add(value1, value2);
Console.WriteLine("Add({0},{1}) = {2}", value1, value2, result);

// Call the Subtract service operation.
value1 = 145.00D;
value2 = 76.54D;
result = client.Subtract(value1, value2);
Console.WriteLine("Subtract({0},{1}) = {2}", value1, value2, result);

// Call the Multiply service operation.
value1 = 9.00D;
value2 = 81.25D;
result = client.Multiply(value1, value2);
Console.WriteLine("Multiply({0},{1}) = {2}", value1, value2, result);

// Call the Divide service operation.
value1 = 22.00D;
value2 = 7.00D;
result = client.Divide(value1, value2);
Console.WriteLine("Divide({0},{1}) = {2}", value1, value2, result);

//Step 3: Closing the client gracefully closes the connection and cleans up resources.
client.Close();


Console.WriteLine();
Console.WriteLine("Press <ENTER> to terminate client.");
Console.ReadLine();

}
}
}

 

قبل از اینکه از client استفاده کنید، مطمئن شوید سرویس در حال اجراست.

برای راه اندازی client، روز Client در Solution Explorer کلیک راست کنید و Debug، سپس Start new instance را انتخاب کنید.

 

Add(100,15.99) = 115.99
Subtract(145,76.54) = 68.46
Multiply(9,81.25) = 731.25
Divide(22,7) = 3.14285714285714
Press <ENTER> to terminate client.

اگر این خروجی را دیدید، پس با موفقیت این کار را انجام داده اید. این مثال، چگونگی پیکر بندی WCF client را در کد نشان می دهد.

چگونگی پیکربندی یک Basic Windows Communication Foundation Client

ارسال شده توسط administrator
23. جوان 2010 17:16

این مقاله، پنجمین مرحله از شش مرحله ای است که باید برای ایجاد یک سرویس Windows Communication Foundation یا (WCF) و یک client که سرویس را فراخوانی می کند، انجام داد.

این مقاله، فایل پیکربندی client را که با استفاده از ServiceModel Metadata Utility Tool (Svcutil.exe) ایجاد شده، به client project اضافه می کند و و محتویات عناصر پیکربندی client را توضیح می دهد. پیکربندی client، شامل تعیین یک endpoint است که client جهت دسترسی به سرویس استفاده می کند. یک endpoint، دارای یک آدرس، یک binding، و یک contract است، و هر یک اینها باید در فرآیند پیکربندی client معین شوند.

محتویات فایل پیکربندی که برای client ایجاد شده، در ادامه آورده شده است.

پیکربندی یک Windows Communication Foundation Client

  1. فایل پیکربندی App.config را که در مقاله قبلی generate شده، به client project در Visual Studio اضافه کنید. روی client project در Solution Explorer کلیک راست کنید، Add و سپس Existing Item را انتخاب کنید. بعداً، فایل پیکربندی App.config را از دایرکتوری که SvcUtil.exe را اجرا کردید، انتخاب کنید. OK کنید. به طور پیش فرض، پنجره Add Existing Item، همه فایل ها را با یک .config فیلتر می کند. برای دیدن این فایل ها، All Files (*.*) را از لیست گوشه سمت راست در پایین پنجره Add Existing Item، انتخاب کنید.
  2. فایل پیکربندی generate را باز کنید. Svcutil.exe، تعدادی value برای هر setting در binding ایجاد می کند. مثال زیر، یک view از فایل پیکربندی generate شده می باشد. در پایین بخش <system.serviceModel>، عنصر <endpoint> را پیدا کنید. فایل پیکربندی زیر، نسخه ساده شده ای از فایل generate شده است.

 


<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ICalculator">
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint
address="http://localhost:8000/ServiceModelSamples/Service/CalculatorService"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ICalculator"
contract="Microsoft.ServiceModel.Samples.ICalculator"
name="WSHttpBinding_ICalculator">
</endpoint>
</client>
</system.serviceModel>
</configuration>

 

این مثال، endpointیی را پیکربندی می کند که client برای دسترسی به سرویسی که در این آدرس

"http://localhost:8000/ServiceModelSamples/service" قرار گرفته، استفاده می کند.

عنصر endpoint، تعیین می کند که از کانترکت Microsoft.ServiceModel.Samples.Icalculator برای ارتباطی استفاده می شود که با WsHttpBinding، که توسط سیستم مهیا شده، پیکربندی می شود.

مثال

این مثال، محتویات فایل پیکربندی را که برای client ایجاد شده، نشان می دهد.

 

<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.serviceModel>
<bindings>
<wsHttpBinding>
<binding name="WSHttpBinding_ICalculator"
closeTimeout="00:01:00"
openTimeout="00:01:00"
receiveTimeout="00:10:00"
sendTimeout="00:01:00"
bypassProxyOnLocal="false"
transactionFlow="false"
hostNameComparisonMode="StrongWildcard"
maxBufferPoolSize="524288"
maxReceivedMessageSize="65536"
messageEncoding="Text"
textEncoding="utf-8"
useDefaultWebProxy="true"
allowCookies="false">
<readerQuotas maxDepth="32"
maxStringContentLength="8192"
maxArrayLength="16384"
maxBytesPerRead="4096"
maxNameTableCharCount="16384" />
<reliableSession ordered="true"
inactivityTimeout="00:10:00"
enabled="false" />
<security mode="Message">
<transport clientCredentialType="Windows"
proxyCredentialType="None"
realm="" />
<message clientCredentialType="Windows"
negotiateServiceCredential="true"
algorithmSuite="Default"
establishSecurityContext="true" />
</security>
</binding>
</wsHttpBinding>
</bindings>
<client>
<endpoint address="http://localhost:8000/ServiceModelSamples/Service/CalculatorService"
binding="wsHttpBinding"
bindingConfiguration="WSHttpBinding_ICalculator"
contract="ICalculator"
name="WSHttpBinding_ICalculator">
<identity>
<userPrincipalName value="user@contoso.com" />
</identity>
</endpoint>
</client>
</system.serviceModel>
</configuration>

 

الان client پیکر بندی شده است.

چگونگی ایجاد یک Windows Communication Foundation Client

ارسال شده توسط administrator
23. جوان 2010 15:06

این مقاله، چهارمین مرحله از شش مرحله ای است که باید برای ایجاد یک سرویس Windows Communication Foundation یا (WCF) و یک client که سرویس را فراخوانی می کند، انجام داد.

این مقاله، چگونگی بازیابی metadata از یک سرویس WCF و استفاده از آن برای ایجاد یک پروکسی WCF که می تواند به سرویس دسترسی داشته باشد را توصیف می کند. این مرحله با استفاده از ServiceModel Metadata Utility Tool (Svcutil.exe) که توسط WCF فراهم می شود، تکمیل می شود. این ابزار metadata را از سرویس بدست می آورد و یک فایل کد مدیریت شده امن برای پروکسی در زبانی انتخابی شما، generate می کند. این ابزار علاوه بر ایجاد client proxy، فایل پیکربندی برای client ایجاد می کند که client application را قادر به وصل شدن به سرویس در یکی از endpointهایش می کند.

client application از پروکسی generate شده برای ایجاد یک WCF client object استفاده می کند.

 

ایجاد یک Windows Communication Foundation client

1. با انجام مراحل زیر، یک پروژه جدید در solution کنونی برای client در Visual Studio 2010 ایجاد کنید.

  • در Solution Explorer، داخل همان solution که سرویس درون آن است، روی solution کنونی کلیک راست کنید و Add و سپس New project را انتخاب کنید.
  • در پنجره Add New Project، Visual Basic یا Visual C# را انتخاب کنید، و سپس Console Application را انتخاب کنید و نام آن را Client بگذارید. از Location پیش فرض استفاده کنید.
  • روی OK کلیک کنید.

2. یک reference به System.ServiceModel.dll برای پروژه اضافه کنید..

  • در زیر پروژه client در Solution Explorer روی پوشه References راست کلیک کنید و Add Reference را انتخاب کنید.
  • تب .NET و سپس System.ServiceModel.dll (نسخه 4.0.0.0) را از لیست انتخاب کنید و OK کنید.

3. یک عبارت using (Imports در VB) برای فضای نامی System.ServiceModel در فایل generate شده Program.cs یا Program.vb اضافه کنید.

در VB

Imports System.ServiceModel

در #C

using System.ServiceModel;

 

4. در Visual Studio، دکمه F5 را بزنید تا سرویس ایجاد شده در مرحله قبلی را شروع کنید.

ServiceModel Metadata Utility Tool (Svcutil.exe) .5. را با switchهای مناسب اجرا کنید تا کد client و فایل پیکربندی را با انجام مراحل زیر، ایجاد کنید.

  • در منوی start، روی All Programs و سپس Visual Studio 2010 کلیک کنید. روی Visual Studio Tools و سپس Visual Studio 2010 Command Prompt کلیک کنید.
  • به دایرکتوری که می خواهید کد client را قرار دهید بروید. اگر پروژه client را به طور پیش فرض ایجاد کرده اید، دایرکتوری، C:\Users\<user name>\My Documents\Visual Studio 10\Projects\Service\Client است.
  • از ابزار خط فرمان ServiceModel Metadata Utility Tool (Svcutil.exe) با switchهای مناسب استفاده کنید تا کد client را ایجاد کنید. مثال زیر، یک فایل کد و یک فایل پیکر بندی برای سرویس generate می کند.

در VB

svcutil.exe /language:vb /out:generatedProxy.vb /config:app.config 
http://localhost:8000/ServiceModelSamples/service
در #C
 
svcutil.exe /language:cs /out:generatedProxy.cs /config:app.config 
http://localhost:8000/ServiceModelSamples/service

به طور پیش فرض، کد پروکسی client، در فایلی که بعد از سرویس نام گذاری می شود، generate می شود. سوییچ /out، نام فایل client proxy را به GeneratedProxy.cs تغیییر می دهد. سوییچ /config، نام فایل پیکربندی client را از Output.config به App.config تغییر می دهد. به خاطر داشته باشید که هردوی این فایل ها در دایرکتوری C:\Users\<user name>\My Documents\Visual Studio 10\Projects\Service\Client ایجاد می شوند.

6. پروکسی generate شده را به client project در Visual Studio اضافه کنید، روی client project در Solution Explorer کلیک راست کنید و Add و سپس Existing Item را انتخاب کنید. فایل generatedProxy را که در مرحله قبل generate شده است را انتخاب کنید.

مثال

کد زیر کد client را که توسط ServiceModel Metadata Utility Tool (Svcutil.exe). ایجاد شده است، نشان می دهد.

 
در VB
 
'----------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
' Runtime Version:2.0.50727.1366
'
' Changes to this file may cause incorrect behavior and
will be lost if
' the code is regenerated.
' </auto-generated>
'-----------------------------------------------------------------

Option Strict Off
Option Explicit On



<System.CodeDom.Compiler.GeneratedCodeAttribute
("System.ServiceModel", "3.0.0.0"), _
System.ServiceModel.ServiceContractAttribute
([Namespace]:="http://Microsoft.ServiceModel.Samples",
ConfigurationName:="ICalculator")> _
Public Interface ICalculator

<System.ServiceModel.OperationContractAttribute
(Action:=
"http://Microsoft.ServiceModel.
Samples/ICalculator/Add"
,
ReplyAction:=
"http://Microsoft.ServiceModel.
Samples/ICalculator/AddResponse"
)> _
Function Add(ByVal n1 As Double,
ByVal n2 As Double) As Double

<System.ServiceModel.OperationContractAttribute
(Action:="http://Microsoft.ServiceModel.
Samples/ICalculator/Subtract"
, ReplyAction:=
"http://Microsoft.ServiceModel.
Samples/ICalculator/SubtractResponse"
)> _
Function Subtract(ByVal n1 As Double,
ByVal n2 As Double) As Double

<System.ServiceModel.OperationContractAttribute
(Action:="http://Microsoft.ServiceModel.
Samples/ICalculator/Multiply"
, ReplyAction:=
"http://Microsoft.ServiceModel.
Samples/ICalculator/MultiplyResponse"
)> _
Function Multiply(ByVal n1 As Double,
ByVal n2 As Double) As Double

<System.ServiceModel.OperationContractAttribute
(Action:="http://Microsoft.ServiceModel.
Samples/ICalculator/Divide"
, ReplyAction:=
"http://Microsoft.ServiceModel.
Samples/ICalculator/DivideResponse"
)> _
Function Divide(ByVal n1 As Double,
ByVal n2 As Double) As Double
End Interface

<System.CodeDom.Compiler.GeneratedCodeAttribute
("System.ServiceModel", "3.0.0.0")> _
Public Interface ICalculatorChannel
Inherits ICalculator, System.
ServiceModel.IClientChannel
End Interface

<System.Diagnostics.DebuggerStepThroughAttribute(), _
System.CodeDom.Compiler.GeneratedCodeAttribute
("System.ServiceModel", "3.0.0.0")> _
Partial Public Class CalculatorClient
Inherits System.ServiceModel.ClientBase(Of ICalculator)
Implements ICalculator

Public Sub New()
MyBase.New
End Sub

Public Sub New(ByVal endpointConfigurationName As String)
MyBase.New(endpointConfigurationName)
End Sub

Public Sub New(ByVal endpointConfigurationName As String,
ByVal remoteAddress As String)
MyBase.New(endpointConfigurationName, remoteAddress)
End Sub

Public Sub New(ByVal endpointConfigurationName As String,
ByVal remoteAddress As System.ServiceModel.EndpointAddress)
MyBase.New(endpointConfigurationName, remoteAddress)
End Sub

Public Sub New(ByVal binding As System.
ServiceModel.Channels.Binding,
ByVal remoteAddress As System.ServiceModel.EndpointAddress)
MyBase.New(binding, remoteAddress)
End Sub

Public Function Add(ByVal n1 As Double,
ByVal n2 As Double)
As Double Implements ICalculator.Add
Return MyBase.Channel.Add(n1, n2)
End Function

Public Function Subtract(ByVal n1 As Double,
ByVal n2 As Double)
As Double Implements ICalculator.Subtract
Return MyBase.Channel.Subtract(n1, n2)
End Function

Public Function Multiply(ByVal n1 As Double,
ByVal n2 As Double)
As Double Implements ICalculator.Multiply
Return MyBase.Channel.Multiply(n1, n2)
End Function

Public Function Divide(ByVal n1 As Double,
ByVal n2 As Double)
As Double Implements ICalculator.Divide
Return MyBase.Channel.Divide(n1, n2)
End Function
End Class

در #C
 
//--------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:2.0.50727.1366
//
// Changes to this file may cause incorrect behavior
and will be lost if
// the code is regenerated.
// </auto-generated>
//-------------------------------------------------------------------



[System.CodeDom.Compiler.GeneratedCodeAttribute
("System.ServiceModel", "3.0.0.0")]
[System.ServiceModel.ServiceContractAttribute
(Namespace="http://Microsoft.ServiceModel.Samples",
ConfigurationName="ICalculator")]
public interface ICalculator
{

[System.ServiceModel.OperationContractAttribute
(Action="http://Microsoft.ServiceModel.
Samples/ICalculator/Add"
, ReplyAction=
"http://Microsoft.ServiceModel.
Samples/ICalculator/AddResponse"
)]
double Add(double n1, double n2);

[System.ServiceModel.OperationContractAttribute
(Action="http://Microsoft.ServiceModel.
Samples/ICalculator/Subtract"
, ReplyAction=
"http://Microsoft.ServiceModel.
Samples/ICalculator/SubtractResponse"
)]
double Subtract(double n1, double n2);

[System.ServiceModel.OperationContractAttribute
(Action="http://Microsoft.ServiceModel.
Samples/ICalculator/Multiply"
, ReplyAction=
"http://Microsoft.ServiceModel.
Samples/ICalculator/MultiplyResponse"
)]
double Multiply(double n1, double n2);

[System.ServiceModel.OperationContractAttribute
(Action="http://Microsoft.ServiceModel.
Samples/ICalculator/Divide"
, ReplyAction=
"http://Microsoft.ServiceModel.
Samples/ICalculator/DivideResponse"
)]
double Divide(double n1, double n2);
}

[System.CodeDom.Compiler.GeneratedCodeAttribute
("System.ServiceModel", "3.0.0.0")]
public interface ICalculatorChannel :
ICalculator, System.ServiceModel.IClientChannel
{
}

[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute
("System.ServiceModel", "3.0.0.0")]
public partial class CalculatorClient :
System.ServiceModel.ClientBase<ICalculator>, ICalculator
{

public CalculatorClient()
{
}

public CalculatorClient
(string endpointConfigurationName) :
base(endpointConfigurationName)
{
}

public CalculatorClient
(string endpointConfigurationName,
string remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}

public CalculatorClient
(string endpointConfigurationName,
System.ServiceModel.EndpointAddress remoteAddress) :
base(endpointConfigurationName, remoteAddress)
{
}

public CalculatorClient
(System.ServiceModel.Channels.Binding binding,
System.ServiceModel.EndpointAddress remoteAddress) :
base(binding, remoteAddress)
{
}

public double Add(double n1, double n2)
{
return base.Channel.Add(n1, n2);
}

public double Subtract(double n1, double n2)
{
return base.Channel.Subtract(n1, n2);
}

public double Multiply(double n1, double n2)
{
return base.Channel.Multiply(n1, n2);
}

public double Divide(double n1, double n2)
{
return base.Channel.Divide(n1, n2);
}
}

الان، شما یک Windows Communication Foundation client ایجاد کرده اید.


چگونگی میزبانی و اجرای یک basic Windows Communication Foundation

ارسال شده توسط administrator
22. جوان 2010 16:53

چگونگی میزبانی و اجرای یک basic Windows Communication Foundation یا (WCF)

این مقاله سومین مرحله از شش مرحله ای است که باید برای ایجاد یک سرویس Windows Communication Foundation یا (WCF) و یک client که سرویس را فراخوانی می کند، انجام داد.

این مقاله، چگونگی اجرای یک سرویس basic Windows Communication Foundation یا (WCF) را توصیف می کند. این فرآیند شامل مراحل زیر است:

  • ایجاد یک ادرس پایه ای برای سرویس
  • ایجاد یک میزبان برای سرویس
  • فعال سازی مبادله فراداده ها
  • باز کردن میزبانی سرویس

لیست کاملی از کدهایی که باید در این مرحله نوشته شوند، در مثال زیر آورده شده است. کد زیر را به متد Main() که در کلاس Program تعریف شده، اضافه کنید. این کلاس هنگامی که شما راه حل Service را ایجاد کردید، generate شده است.

پیکر بندی آدرس پایه (base address) برای سرویس

  1. یک نمونه Uri برای آدرس پایه ای سرویس ایجاد کنیم. این URI، سیستم محلی شما، پورت شماره 8000، HTTP scheme و مسیر ServiceModelSample/Service را به سرویسی که برای فضای نامی سرویس در service contract معین شده، تعیین می کند.

در VB

در#C

Uri baseAddress = new Uri("http://localhost:8000/ServiceModelSamples/Service");

میزبانی سرویس

    1. فضای نامی System.ServiceModel.Description را import کنید. این کد باید در بالای فایل Program.cs/Program.vb با بقیه عبارات using یا imports، قرار گیرد.

در VB

Imports System.ServiceModel.Description

در#C

using System.ServiceModel.Description;

    2. نمونه ای جدید از ServiceHost برای میزبانی سرویس ایجاد کنید. باید typeیی را که service contract و base address را پیاده سازی می کند، تعیین کنید. آدرس پایه ای این نمونه، http://localhost:8000/ServiceModelSamples/Service است، و CalculatorService، تایپی است که service contract را پیاده سازی می کند.

در VB

Dim selfHost As New ServiceHost(GetType(CalculatorService), baseAddress)

در#C

ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);

    3. یک عبارت try-catch اضافه کنید که CommunicationException را catch می کند و کد را در سه مرحله بعدی اضافه کنید و block را try کنید. کلمه catch، باید یک پیام error نمایش دهد، سپس selfHost.Abort() را فراخوانی کنید.

در VB

Try
' ...
Catch ce As CommunicationException
Console.WriteLine("An exception occurred: {0}", ce.Message)
selfHost.Abort()
End Try

در#C

try
{
// ...
}
catch (CommunicationException ce)
{
Console.WriteLine("An exception occurred: {0}", ce.Message);
selfHost.Abort();
}

    4. یک endpoint اضافه کنید که سرویس را expose کند. برای انجام این کار، باید contractیی را که endpoint در حال expose کردن است، تعیین کنید. برای این نمونه، ICalculator را به عنوان contract، WSHttpBinding را به عنوان binding، و CalculatorService را به عنوان آدرس تعیین کنید. توجه داشته باشید که در اینجا آدرس endpoint، یک آدرس رابطه ای است. آدرس کامل endpoint، ترکیبی از آدرس پایه ای و آدرس endpoint است. در این مورد، آدرس کامل http://localhost:8000/ServiceModelSamples/Service/CalculatorService است.

در VB

' Add a service endpoint
selfHost.AddServiceEndpoint( _
GetType(ICalculator), _
New WSHttpBinding(), _
"CalculatorService")

در#C

selfHost.AddServiceEndpoint(
typeof(ICalculator),
new WSHttpBinding(),
"CalculatorService");

    5. تبادل فرا داده ها را فعال کنید. برای انجام این کار، یک service metadata behavior اضافه کنید. ابتدا یک نمونه از ServiceMetadataBehavior ایجاد کنید، HttpGetEnabled را روی true تنظیم کنید، و سپس behavior جدید به سرویس اضافه کنید.

در VB

' Enable metadata exchange
Dim smb As New ServiceMetadataBehavior()
smb.HttpGetEnabled = True
selfHost.Description.Behaviors.Add(smb)

در#C

ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
selfHost.Description.Behaviors.Add(smb);

    6. ServiceHost را باز کنید و منتظر پیامهای دریافتی بمانید. هنگامی که کاربر دکمه enter را می زند، ServiceHost را ببندید.

در VB

selfHost.Open()
Console.WriteLine("The service is ready.")
Console.WriteLine("Press <ENTER> to terminate service.")
Console.WriteLine()
Console.ReadLine()

' Close the ServiceHostBase to shutdown the service.
selfHost.Close()

در#C

selfHost.Open();
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();

// Close the ServiceHostBase to shutdown the service.
selfHost.Close();

تایید کار کردن سرویس

1. service.exe را از داخل Visual Studio اجرا کنید. زمان اجرا روی ویندوز ویستا، سرویس باید با اجازه مدیر (administrator) اجرا شود. زیرا Visual Studio و service.exe با اجازه مدیر اجرا می شوند. می توانید با اجازه مدیر، یک command prompt جدید باز کنید و service.exe را درون آن اجرا کنید.

2. Internet Explorer را باز کنید و به صفحه دیباگ سرویس به آدرس http://localhost:8000/ServiceModelSamples/Service بروید.

مثال

مثال زیر، شامل service contract و پیاده ساری آن از مرحله قبلی می باشد، و سرویس را در یک console application میزبانی می کند.

در VB

Imports System
Imports System.ServiceModel
Imports System.ServiceModel.Description

Module Service
' Define a service contract.
<ServiceContract(Namespace:="http://Microsoft.ServiceModel.Samples")> _
Public Interface ICalculator
<OperationContract()> _
Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double
<OperationContract()> _
Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double
<OperationContract()> _
Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double
<OperationContract()> _
Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double
End Interface

' Service class that implements the service contract.
' Added code to write output to the console window.
Public Class CalculatorService
Implements ICalculator
Public Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Add
Dim result As Double = n1 + n2
Console.WriteLine("Received Add({0},{1})", n1, n2)
Console.WriteLine("Return: {0}", result)
Return result
End Function

Public Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Subtract
Dim result As Double = n1 - n2
Console.WriteLine("Received Subtract({0},{1})", n1, n2)
Console.WriteLine("Return: {0}", result)
Return result
End Function

Public Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Multiply
Dim result As Double = n1 * n2
Console.WriteLine("Received Multiply({0},{1})", n1, n2)
Console.WriteLine("Return: {0}", result)
Return result
End Function

Public Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Divide
Dim result As Double = n1 / n2
Console.WriteLine("Received Divide({0},{1})", n1, n2)
Console.WriteLine("Return: {0}", result)
Return result
End Function
End Class

Class Program
Shared Sub Main()
' Step 1 of the address configuration procedure: Create a URI to serve as the base address.
Dim baseAddress As New Uri("http://localhost:8000/ServiceModelSamples/Service")

' Step 2 of the hosting procedure: Create ServiceHost
Dim selfHost As New ServiceHost(GetType(CalculatorService), baseAddress)
Try

' Step 3 of the hosting procedure: Add a service endpoint.
' Add a service endpoint
selfHost.AddServiceEndpoint( _
GetType(ICalculator), _
New WSHttpBinding(), _
"CalculatorService")

' Step 4 of the hosting procedure: Enable metadata exchange.
' Enable metadata exchange
Dim smb As New ServiceMetadataBehavior()
smb.HttpGetEnabled = True
selfHost.Description.Behaviors.Add(smb)

' Step 5 of the hosting procedure: Start (and then stop) the service.
selfHost.Open()
Console.WriteLine("The service is ready.")
Console.WriteLine("Press <ENTER> to terminate service.")
Console.WriteLine()
Console.ReadLine()

' Close the ServiceHostBase to shutdown the service.
selfHost.Close()
Catch ce As CommunicationException
Console.WriteLine("An exception occurred: {0}", ce.Message)
selfHost.Abort()
End Try
End Sub
End Class
در#C
using System;
using System.ServiceModel;
using System.ServiceModel.Description;

namespace Microsoft.ServiceModel.Samples
{
// Define a service contract.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);
}

// Service class that implements the service contract.
// Added code to write output to the console window.
public class CalculatorService : ICalculator
{
public double Add(double n1, double n2)
{
double result = n1 + n2;
Console.WriteLine("Received Add({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}

public double Subtract(double n1, double n2)
{
double result = n1 - n2;
Console.WriteLine("Received Subtract({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}

public double Multiply(double n1, double n2)
{
double result = n1 * n2;
Console.WriteLine("Received Multiply({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}

public double Divide(double n1, double n2)
{
double result = n1 / n2;
Console.WriteLine("Received Divide({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}
}
class Program
{
static void Main(string[] args)
{

// Step 1 of the address configuration procedure: Create a URI to serve as the base address.
Uri baseAddress = new Uri("http://localhost:8000/ServiceModelSamples/Service");

// Step 2 of the hosting procedure: Create ServiceHost
ServiceHost selfHost = new ServiceHost(typeof(CalculatorService), baseAddress);

try
{


// Step 3 of the hosting procedure: Add a service endpoint.
selfHost.AddServiceEndpoint(
typeof(ICalculator),
new WSHttpBinding(),
"CalculatorService");


// Step 4 of the hosting procedure: Enable metadata exchange.
ServiceMetadataBehavior smb = new ServiceMetadataBehavior();
smb.HttpGetEnabled = true;
selfHost.Description.Behaviors.Add(smb);

// Step 5 of the hosting procedure: Start (and then stop) the service.
selfHost.Open();
Console.WriteLine("The service is ready.");
Console.WriteLine("Press <ENTER> to terminate service.");
Console.WriteLine();
Console.ReadLine();

// Close the ServiceHostBase to shutdown the service.
selfHost.Close();
}
catch (CommunicationException ce)
{
Console.WriteLine("An exception occurred: {0}", ce.Message);
selfHost.Abort();
}

}
}
}

الان سرویس در حال اجراست.

چگونگی پیاده سازی یک Windows Communication Foundation Service Contract

ارسال شده توسط administrator
22. جوان 2010 13:42

چگونگی پیاده سازی یک Windows Communication Foundation Service Contract

این مقاله، دومین کار از شش کاری است که باید برای ایجاد یک سرویس Windows Communication Foundation یا (WCF) و یک client که سرویس را فراخوانی می کند، انجام داد.

برای ایجاد یک سرویس WCF، ابتدا باید یک contract ایجاد کرد، که با استفاده از یک اینترفیس تعریف می شود. برای کسب اطلاعات بیشتر در مورد چگونگی یک interface، اینجا کلیک کنید. مرحله بعدی، که در این مثال نشان داده شده است، پیاده سازی اینترفیس است. این کار مستلزم ایجاد یک کلاس بنام CalculatorService است که اینترفیس ICalculator را که توسط کاربر تعریف شده، پیاده می کند. کدی که برای این کار استفاده می شود در زیر آورده شده است.

پیاده سازی یک WCF service contract

یک کلاس جدید بنام CalculatorService در همان فایلی که اینترفیس ICalculator را تعریف کردید، ایجاد کنید. این کلاس، اینترفیس ICalculator را پیاده سازی می کند.

 

در VB

 

Public Class CalculatorService
Implements ICalculator

در #C

public class CalculatorService : ICalculator

هر متدی را که در اینترفیس ICalculator و داخل کلاس CalculatorService تعریف شده، پیاده سازی کنید.

 

در VB

Public Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Add
Dim result As Double = n1 + n2
' Code added to write output to the console window.
Console.WriteLine("Received Add({0},{1})", n1, n2)
Console.WriteLine("Return: {0}", result)
Return result
End Function

Public Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Subtract
Dim result As Double = n1 - n2
Console.WriteLine("Received Subtract({0},{1})", n1, n2)
Console.WriteLine("Return: {0}", result)
Return result

End Function

Public Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Multiply
Dim result As Double = n1 * n2
Console.WriteLine("Received Multiply({0},{1})", n1, n2)
Console.WriteLine("Return: {0}", result)
Return result

End Function


Public Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Divide
Dim result As Double = n1 / n2
Console.WriteLine("Received Divide({0},{1})", n1, n2)
Console.WriteLine("Return: {0}", result)
Return result

End Function

در #C

public double Add(double n1, double n2)
{
double result = n1 + n2;
Console.WriteLine("Received Add({0},{1})", n1, n2);
// Code added to write output to the console window.
Console.WriteLine("Return: {0}", result);
return result;
}

public double Subtract(double n1, double n2)
{
double result = n1 - n2;
Console.WriteLine("Received Subtract({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}

public double Multiply(double n1, double n2)
{
double result = n1 * n2;
Console.WriteLine("Received Multiply({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}

public double Divide(double n1, double n2)
{
double result = n1 / n2;
Console.WriteLine("Received Divide({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}

مثال

کد زیر هم اینترفیسی را که contract را تعریف می کند، و هم پیاده سازی اینترفیس را نشان می دهد.

در VB

Imports System
Imports System.ServiceModel


Namespace Microsoft.ServiceModel.Samples
' Define a service contract.
<ServiceContract([Namespace] := "http://Microsoft.ServiceModel.Samples")> _
Public Interface ICalculator
<OperationContract()> _
Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double
<OperationContract()> _
Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double
<OperationContract()> _
Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double
<OperationContract()> _
Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double
End Interface

' Step 1: Create service class that implements the service contract.
Public Class CalculatorService
Implements ICalculator

' Step 2: Implement functionality for the service operations.
Public Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Add
Dim result As Double = n1 + n2
' Code added to write output to the console window.
Console.WriteLine("Received Add({0},{1})", n1, n2)
Console.WriteLine("Return: {0}", result)
Return result
End Function

Public Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Subtract
Dim result As Double = n1 - n2
Console.WriteLine("Received Subtract({0},{1})", n1, n2)
Console.WriteLine("Return: {0}", result)
Return result

End Function

Public Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Multiply
Dim result As Double = n1 * n2
Console.WriteLine("Received Multiply({0},{1})", n1, n2)
Console.WriteLine("Return: {0}", result)
Return result

End Function


Public Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double Implements ICalculator.Divide
Dim result As Double = n1 / n2
Console.WriteLine("Received Divide({0},{1})", n1, n2)
Console.WriteLine("Return: {0}", result)
Return result

End Function
End Class
End Namespace

در #C

using System;
using System.ServiceModel;

namespace Microsoft.ServiceModel.Samples
{
// Define a service contract.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);
}

// Step 1: Create service class that implements the service contract.
public class CalculatorService : ICalculator
{
// Step 2: Implement functionality for the service operations.
public double Add(double n1, double n2)
{
double result = n1 + n2;
Console.WriteLine("Received Add({0},{1})", n1, n2);
// Code added to write output to the console window.
Console.WriteLine("Return: {0}", result);
return result;
}

public double Subtract(double n1, double n2)
{
double result = n1 - n2;
Console.WriteLine("Received Subtract({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}

public double Multiply(double n1, double n2)
{
double result = n1 * n2;
Console.WriteLine("Received Multiply({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}

public double Divide(double n1, double n2)
{
double result = n1 / n2;
Console.WriteLine("Received Divide({0},{1})", n1, n2);
Console.WriteLine("Return: {0}", result);
return result;
}
}
}

الان، service contract ایجاد و پیاده سازی شده است. یک solution بسازید تا مطمئن شوید که هیچ error در compilation وجود ندارد.

چگونگی تعریف یک Windows Communication Foundation Service Contract

ارسال شده توسط administrator
21. جوان 2010 12:22

این مقاله، 6 کار ابتدایی لازم برای ایجاد یک سرویس پایه ای Windows Communication Foundation یا (WCF) و یک client است که می تواند سرویس را فراخوانی کند.

هنگام ایجاد یک basic WCF service، اولین کار، تعریف یک contract است. contract تعیین می کند service چه عملیات هایی را ساپورت کند. می توان یک عملیات را یک متد وب سرویس در نظر گرفت. Contractها بوسیله تعریف یک interface در C++، C#، یا VB ایجاد می شود. هر متد در interface، معادل یک service operation معین است. هر interface باید ServiceContractAttribute و هر operation باید دارای OperationContractAttribute باشد که به آن اعمال شده باشد. اگر متدی در یک interface که ServiceContractAttribute دارد ولی OperationContractAttribute ندارد، آن متد expose نمی شود.

کدی که برای این کار استفاده می شود در زیر آورده شده.

چگونگی ایجاد یک Windows Communication Foundation contract با یک interface

1. Visual Studio 2010 راas administrator باز کنید. (در منوی start، روی برنامه کلیک راست کنید و Run as administrator را اجرا کنید).

2. یک console application project جدید ایجاد کنید. روی منوی file کلیک کنید و New، و سپس Project را انتخاب کنید. در پنجره New Project، Visual Basic یا Visual C# را انتخاب کنید، و سپس Console Application template را انتخاب کنید، و نام آن را Service بگذارید. از Location پیش فرض استفاده کنید.

3. برای پروژه C#، یک فایل بنام Program.cs توسط Visual Studio ایجاد می شود. این کلاس حاوی یک متد خالی به نام Main() است؛ و برای پروژه VB، یک فایل بنام Module1.vb با یک subroutine خالی بنام Main() ایجاد می شود. این متدها برای اینکه یک console application project درست ساخته شود ضروری هستند، پس می توان آنها را با خیال راحت در پروژه رها کرد.

4. فضای نامی Service پیش فرض را به Microsoft.ServiceModel.Samples تغییر دهید. برای انجام این کار، روی پروژه در Solution Explorer کلیک راست کنید و Properties را انتخاب کنید. مطمئن شوید که تب Application در سمت چپ Properties dialog ، انتخاب شده باشد. برای پروژه C#، عبارت Microsoft.ServiceModel.Samples را در edit box که نامش Default Namespace است، تایپ کنید. برای پروژه VB, عبارت Microsoft.ServiceModel.Samples را در edit box که نامش Root namespace است، تایپ کنید. روی منوی File کلیک کنید و save all را انتخاب کنید تا تغییرات ذخیره شوند.

5. اگر از C# استفاده می کنید، namespaceیی را که در فایل Program.cs ایجاد شده به Microsoft.ServiceModel.Samples تغییر د هید، همانگونه که در در زیر نشان داده شده:

 

namespace Microsoft.ServiceModel.Samples 
{
class Program
{
static void Main(string[] args)
{
}
}
}

 

اگر از VB استفاده می کنید، یک عبارت Namespace و یک عبارت End Namespace به Module1.vb اضافه کنید، همانگونه که در مثال زیر نشان داده شده است.

 

Namespace Microsoft.ServiceModel.Samples
Module Module1
Sub Main()
End Sub
End Module
End Namespace

 

6. یک refertence به System.ServiceModel.dll به پروژه اضافه کنید:

در Solution Explorer، روی پوشه References زیر پوشه پروژه، راست کلیک کنید و Add Reference را انتخاب کنید.

در Add Reference dialog، تب .NET را انتخاب کنید و بروید پایین تا System.ServiceModel را ببینید، ان را انتخاب کنید و OK را کلیک کنید.

نکته:

هنگام استفاده از command-line compiler (مثلاً Csc.exe یا Vbc.exe)، باید مسیری را نیزبه assemblyها مشخص کنید. در کامپوتری که مثلاً دارای ویندوز ویستا است، مسیر پیش فرض "Windows\Microsoft.NET\Framework\v4.0" است.

7. یک عبارتusing (imports در VB) برای فضای نامی System.ServiceModel اضافه کنید.

در C#:

using System.ServiceModel;

 

در VB:

Imports System.ServiceModel

8. یک interface جدید بنام ICalculator تعریف کنید و صفت ServiceContractAttribute را به آن interface با valueی فضای نامی "http://Microsoft.ServiceModel.Samples" اعمال کنید. تعیین فضای نامی به طور مستقیم، بهترین روش است زیرا به valueی فضای نامی پیش فرض اجازه نمی دهد به contract name اضافه شود.

نکته:

هنگام استفاده از صفات برای نوشتن یادداشت زیر یک interface یا کلاس، می توانید قسمت "Attribute" را از نام صفت، drag کنید. پس ServiceContractAttribute در C#تبدیل به [ServiceContract]، و در VB، تبدیل به <ServiceContract> می شود.

در C#:

[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface Icalculator

در VB:

<ServiceContract(Namespace:="http://Microsoft.ServiceModel.Samples")> _
Public Interface ICalculator

 

9. متدی را برای هر یک از عملیاتهایی که ICalculator contract، در اینترفیس expose می کند (add، subtract، multiply، و devide)، تعریف کنید و صفت OperationContractAttribute را به هر متدی که می خواهید به عنوان بخشی از WCF contract عمومی expose کنید، اعمال کنید.

در C#:

[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);

در VB:

<OperationContract()> _
nction Add(ByVal n1 As Double, ByVal n2 As Double) As Double
<OperationContract()> _
Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double
<OperationContract()> _
Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double
<OperationContract()> _
Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double

مثال: کد زیر یک ایتنرفیس پایه ای را نشان می دهد که یک service contract را تعریف می کند.

در C#:

using System;
// Step 5: Add the using statement for the System.ServiceModel namespace
using System.ServiceModel;
namespace Microsoft.ServiceModel.Samples
{
// Step 6: Define a service contract.
[ServiceContract(Namespace = "http://Microsoft.ServiceModel.Samples")]
public interface ICalculator
{
// Step7: Create the method declaration for the contract.
[OperationContract]
double Add(double n1, double n2);
[OperationContract]
double Subtract(double n1, double n2);
[OperationContract]
double Multiply(double n1, double n2);
[OperationContract]
double Divide(double n1, double n2);
}
}

در VB:

Imports System
' Step 5: Add the Imports statement for the System.ServiceModel namespace
Imports System.ServiceModel

Namespace Microsoft.ServiceModel.Samples
' Step 6: Define a service contract.
<ServiceContract(Namespace:="http://Microsoft.ServiceModel.Samples")> _
Public Interface ICalculator
<OperationContract()> _
Function Add(ByVal n1 As Double, ByVal n2 As Double) As Double
<OperationContract()> _
Function Subtract(ByVal n1 As Double, ByVal n2 As Double) As Double
<OperationContract()> _
Function Multiply(ByVal n1 As Double, ByVal n2 As Double) As Double
<OperationContract()> _
Function Divide(ByVal n1 As Double, ByVal n2 As Double) As Double
End Interface
End Namespace

الان، اینترفیس ایجاد شده است.