2016-11-11 umtp モデリングフォーラム2016...

54
Modeling Forum 2016 2016年11月11日 株式会社ネクストスケープ 上坂 貴志 DDD 実践のコツと Microsoft Azure による モデル実装のご紹介 ALLPPT.com _ Free PowerPoint Templates, Diagrams and Charts

Upload: -

Post on 16-Apr-2017

372 views

Category:

Software


2 download

TRANSCRIPT

Modeling Forum 20162016年11月11日

株式会社ネクストスケープ上坂 貴志

DDD実践のコツとMicrosoft Azureによるモデル実装のご紹介

ALLPPT.com _ Free PowerPoint Templates, Diagrams and Charts

自己紹介

会社 株式会社ネクストスケープ

名前、年齢 上坂貴志(うえさかたかし)44歳 Twitter:@takashiuesaka

好き・興味

Azure( Microsoft MVP for Microsoft Azure)

Scrum( 認定スクラムマスター)

DDD、ソフトウェアアーキテクチャ、機械学習

講演活動

2016年

QCon Tokyo 2016 DDD実践報告

de:code 2016 DDD & Azure Service Fabric 登壇

NS Study No.6 Azure IoTHub紹介 登壇

アプレッソ 最新IT事例セミナー Azure Machine Learning セミナー登壇

SANSAN DDD勉強会発表

2015年

FEST2015 (Channel9で動画公開)

Developers Summit 2015

QCon Tokyo 2015

執筆活動 人工知能アプリケーション総覧 寄稿(日経BP社)

会社紹介

株式会社ネクストスケープ

2002年設立、今は西新宿にオフィスがあります

豆蔵ホールディングスのグループ会社です

システムインテグレーターの会社です

会社紹介

株式会社ネクストスケープ

Microsoft Azureを使ったシステム開発に自信あります

動画・音楽配信のソリューションよくやってます

ECサイト、DAM、デジタルマーケティングも多いです

会社紹介

株式会社ネクストスケープ

DDDやろうぜ Scrumやろうぜ

SESやっていないので、自社で開発100%ですよ

只今、エンジニア積極採用中です

なぜDDDか

なぜDDDか

DDDとは

2011年、DDDの著者 Eric Evans氏が来日。QCon Tokyo 2011にて講演

2011年発売2003年発売 2015年発売2008年発売

なぜDDDか

システム開発の問題点とは何か

ユーザーからの不満

開発側が自分たちのビジネスを良く知らない

解決したい課題・達成したい事がちゃんと伝わっているかわからない

そもそも伝えるのに時間がかかり過ぎる

納品されてから伝わってなかったことに気が付くなんて最悪

Section 1/5 total 1/13

なぜDDDか

システム開発の問題点とは何か

システム開発側視点

ユーザーの話は目的と手段が混在していて整理が大変

ユーザーからの話は解決したい課題や、達成したいことそのものとは限らない。背景まで説明してくれないことも多い。そのため、ユーザーからヒアリングした内容をどう達成するか、に終始してしまいがち

要求を整理するためには、ユーザーのビジネスや業界、会社、ユーザーの部門の状態に精通するのが近道なのはわかっているが、これらに対して短時間で精通するのは無理

Section 2/5 total 2/13

なぜDDDか

原因はなに?

ユーザーとシステム開発側、双方が持つ暗黙知が悪さをする

ユーザーからすると、一所懸命説明してるし、開発者側の反応を見ていると全て(業界、ビジネス、自社の状態、部門の都合など)わかっているかのように見える

開発者は自分のもつ一般常識(業界、ビジネス)に当てはめ、わかったつもりで話を進めてしまう

どうしてもズレが発生してしまう

さらにいうと、ユーザーは本当は何をしたいのかわかっていないことも

Section 3/5 total 3/13

DDDとは

DDDが提案する複雑さに対する解

解決したい事・達成したい事(ドメイン)に対して、ユーザーと開発者との間で共通の言葉を定義していく

その言葉が直感的ではないなら、両者合意の上で新しい言葉(直感的なもの)を策定していく

ユビキタス言語はモデル名やメソッド名、パッケージ名などあらゆる箇所で実際に使用する(ただの用語辞書扱いではなく)

ユビキタス言語

Section 4/5 total 4/13

DDDとは

DDDが提案する複雑さに対する解

解決したい課題、達成したいこと(ドメイン)をモデルとして表現することで、目的に向かっているのかをユーザー・開発者双方から確認することができる

ただし、分析用のモデルと実装用のモデルと2つ用意しないで、1つのモデルで表現する(フェーズ間の変換をしない)

モデル駆動による設計

Section 5/5 total 5/13

DDDとは

ユビキタス言語を定義しながらモデリングをしていくと、言葉の意味が曖昧となってしまって混乱することがよくある。原因は、

違うものを同じ言葉で表している

同じものを違う言葉で表している

から。これは本来コンテキストが異なるのに、1つのコンテキストですべてを語ろうとしているために起こる。

コンテキストを分割して、それぞれの言葉の意味を正確に確定していく。

(コンテキストは複数になって、コンテキストそれぞれでモデリングする)

DDDが提案する複雑さに対する解

境界づけられたコンテキスト

DDDとは

DDDが提案する複雑さに対する解

• ドメインを理解する人(要件定義)

• モデリングをする人(基本設計)

• 実装する人(詳細設計~実装~テスト)

これが全てバラバラの人が実施するからズレが生じやすくなる。

メンバー全員がドメインを理解し、モデリングすることが大事。つまりプログラマーであってもモデリングを行い、ドメインの理解は必須となる。

実践的モデラー

DDD実践報告

DDD実践報告

影も形も残らなかった

当時の状況 設計フェーズ以降から開発側だけで勝手にDDDを始めた

ソフトウェアアーキテクチャとモデリングの導入だけでも恩恵を受けることができると思った

結果は大失敗 最初はうまくいきそうだったが、あっという間に一般的な3層レイヤーと同じになった

当時の振り返り

メンバーにDDDを教育しないで始めてしまったため、メンバーがモデリング→実装をイメージできなかった

モデリングだけなら教育なしでもある程度は形になるかと思ったが、全くモデリングできなかった

途中参画メンバーが「ドメインサービス」を多用。貧血ドメインになってしまった。このメンバーはDDDに興味がなかった

Section 1/7 total 6/13

DDD実践報告

モデリング・実装がうまくいかない

当時の状況

メンバーにはDDDに興味があり、かつDDDを教育した人をアサイン

ユーザーにもDDDを説明し、ユビキタス言語の作成協力に快諾いただく

モデリングをしつつ、実装してみる流れでやってみた

結果は大失敗 モデリングは初期しか行われなかった。あっという間に実装だけになった

当時の振り返り

ER図から脱却できなかった。モデリングではなく、ER図になっていた

集約のついての知識が足りないためにモデリング時に集約を意識しなかった

モデリングした結果と実装がどうしてもうまくMappingしなかった

RepositoryやFactoryをどこに実装するのかなどドメイン以外のついて議論になってしまってスタートから躓いたことで焦ってしまったため、モデリングがさらに疎かに

Specification, 副作用のない関数、閉じた操作などの「しなやかな設計」への意識がないなど、モデリングの知識・技量が足りなかった

Section 2/7 total 7/13

DDD実践報告

失敗と改善を繰り返した後の振り返り

原因は色々あるけど、理由は恐らく「不安」

ベテランであればあるほど、今までのやり方との差異が気になって仕方がない

開発プロセスへの不安

要件をヒアリングしながらモデリングは理解できるけど・・・

その結果は納品物なの?

モデリングは基本設計まで踏み込んでいるの?

要件定義にかかるコストとスケジュールは今まで通りでいいの?

要件定義の次は何するの?

実装フェーズのコストは増えるのでは?どれぐらい増えるのかをどうやって見積もるの?

オブジェクト指向を採用することの不安

過去にオブジェクト指向を勉強したけど、全く実システムに関係なかった、という人が多い。無駄な作業、という認識

Section 3/7 total 8/13

DDD実践報告

という認識のベテランがものすごく多い!

この認識を変えてもらわないモデリングできない・・・

失敗と改善を繰り返した後の振り返り

でも、実は最大の原因はモデリングに対するベテランの驕りなのではないか、とも。

オブジェクト指向ができる=モデリングができる

モデリング=ER図と大差ない

Section 4/7 total 9/13

DDD実践報告

その後、DDD導入・実践に成功

開発プロセスの不安への対処

ユーザーにしっかりとユビキタス言語の共同作成について認識してもらう

開発プロセスの最初からモデリング

ベテランに対してDDDをしっかり教育

特に開発プロセスについて疑問がないように以下を伝える

モデリング結果は納品物にする

モデリングは基本設計まで踏み込んでいる、とする

要件定義にかかるコスト・スケジュールの増加を事前にユーザーに理解をしてもらう

要件定義の次のフェーズは実装。ソフトウェアアーキテクチャテンプレートの修正、モデリング結果の実装、UI実装。DB設計はある程度要件が固まってきてから行う

Section 5/7 total 10/13

DDD実践報告

その後、DDD導入・実践に成功

実装上の不安への対処

しっかりとしたソフトウェアアーキテクチャとサンプルを用意

モデリング結果が実装になることを示す

モデル以外のレイヤーの具体例を示す

モデルをドメインレイヤーに閉じ込めることで、変更に対してもうまく対処できるように

Section 6/7 total 11/13

DDD実践報告

すべてうまくはいかなかった

•複雑なドメインをモデルとして抽象化→実装はそれなりにうまくいった

•モデリングに興味のない人は最後まで興味がない

•時間がなくなってくると、Mappingの実装が面倒になって次第にSQLやRepositryにビジネス

ロジックが混入し始める

【まとめ】成功・・・なの?

でも、しばらく経ってから再度ソースを見直してみると、あちこちモデリングがおかしいな、というところに気が付くように。

わからないながらも、モデリングと勉強を繰り返すと技量はあがるらしい。モデリングもコードも良くなっていくことを実感

※でも、DDDにはブレイクスルーが必要だな、とも。

Section 7/7 total 12/13

~これから始めるDDD~

モデリング時のポイント

モデリング時のポイント

1.静的構造を表すモデルにしないこと(そこで止まらないこと)

静的構造だけを表したモデルを作っても、実装には全く意味がなかった。意味がないどころか、貧血ドメインまっしぐらになってしまうため、害悪そのものだった。

ユースケースを常に意識すること、どのモデルがどのビジネスロジックを持つべきなのかを考え続けることで無意味な静的構造モデルから、実装できるモデルに一歩近づく。

タイヤ

タイヤ

車輪

位置

1 4

4

*

期間走行距離

rotate()

静的構造だけのモデリング ビジネスロジックを意識したモデリング

例:タイヤのローテーションを行う

走行距離

車輪4

※位置はタイヤがどの車輪にどの期間ついていたのかを表す履歴となり、次にどこに位置にローテーションするかを判断する条件となる

位置

モデリング時のポイント

2.1つのモデルによる中央集権にならないようにする

DAM(Digital Asset Management)のシステムの場合

コンテンツ

メタ

カテゴリ

グループ ファイルパス

サムネイルパス

作成者

作成者Id

パスワード

氏名

所属

登録日公開日公開終了日

コンテンツ

コンテンツ

作成者

作成者Id

メタ

メタId

中央集権モデル 集約でパッケージングして、Idで連携

集約を強く意識しないと、すぐに中央に王様を配置したモデルとなってしまう。

これを分割する時のコツは、モデルを直接参照しあうのではなく、Id越しに参照する。

モデリング時のポイント

3.ビジネスロジックの置き場所に困った時は「仕様パターン」!

例えば、勤怠管理システムにて打刻日時から勤務日を判定する場合

・勤務日は実際の打刻日時とは異なる場合がある。

・例えば、11/10の24時を5分回った場合、勤務日は11/11ではなく、11/10のままである。

12

6

39

12

1110

78 4

5

・つまり、実際の日付と、勤務日の日時はズレることがある。

・ちなみにネクストスケープではAM4:59までは勤務日は前日扱いとなる。(!)

・これをどうやってモデリングする?

12

6

39

12

1110

78 4

5

打刻時刻:11/10 23:55勤務日 :11/10

打刻時刻:11/11 0:05勤務日 :11/10 打刻時刻とずれる

モデリング時のポイント

・打刻日時が勤務日を返すプロパティを実装するモデリング

3.ビジネスロジックの置き場所に困った時は「仕様パターン」!

打刻日時 勤務日

Get勤務日()

new

実装例

・var touch = new 打刻日時(DateTime stampedDateTime);

・勤務日 workday = touch.Get勤務日();

この場合、何時を基準に勤務日が何日なのか判定ロジックを打刻日時が持つことになる。

でもこれはなんか変。

・打刻日時が勤務日の生成に関する条件を知っているの?

・そもそも打刻日時が勤務日を生成する責務を負うの?単一責任の原則(SRP)に反していない?

(勤務日判定条件が変わったら、打刻日時を変更するの?打刻日時なのに?)

モデリング時のポイント

・勤務日が打刻日時を受け取るモデリング

3.ビジネスロジックの置き場所に困った時は「仕様パターン」!

勤務日

勤務日(打刻日時 stampedDateTime)

実装例

・var workday = new 勤務日(new 打刻日時(DateTime stampedDateTime));

ちょっと良さそう!でもよく考えると、勤務日に対して打刻日時は複数存在することに気がつく。

つまり勤務日は毎回生成するのではなく、既に存在している場合はそれをRepositoryより復元して、打刻日時を追加することになる(Addメソッドを持つ)はず。

(※集約のルートエンティティとなる可能性大)

勤務日 打刻日時*

勤務日

Add(打刻日時)

打刻日時

打刻日時*

モデリング時のポイント

・勤務日が打刻日時を受け取るモデリング

3.ビジネスロジックの置き場所に困った時は「仕様パターン」!

つまり打刻があった場合、まず既に存在している勤務日をRepositoryに問い合わせて、もし存在したら復元した勤務日に打刻日時を追加することになる。

ということは、Repositoryに打刻日時を渡して、勤務日を取得してきてもらわなくてはならない。

あれ?Repositoryが打刻日時から勤務日を判定するロジックを持つことになる?

それはおかしい・・・。どうしたらいいんだろうか・・・

勤務日勤務日Repository

FindBy打刻日時(打刻日時)

復元

Add(打刻日時)

打刻日時*

モデリング時のポイント

・勤務日仕様というValueObjectをモデルに追加する。このモデルに勤務日と打刻日時の整合性チェックの責務を担当させる。

・勤務日仕様には isSatisfy(勤務日 workDay, 打刻日時 touch)メソッドを持たせる。このメソッドが整合性チェックの結果をboolで返却する。

3.ビジネスロジックの置き場所に困った時は「仕様パターン」!

勤務日仕様

勤務日仕様(TimeSpan)IsSatisfy(勤務日, 打刻日時)

勤務日勤務日Repository

FindBy打刻日時(打刻日時,勤務日仕様)

復元

Add(打刻日時)

打刻日時*

Factory

Factory(打刻日時,勤務日仕様)

Create()

生成

モデリング時のポイント

生成の実装例

var touch = new 打刻日時(stampedDateTime);

var spec = new 勤務日仕様(standardTime);

// Factoryクラスは、勤務日クラス内部に用意する

var workday = new 勤務日.Factory(touch, spec).Create();

Repositoryの実装例

・var workday = new 勤務日Repository().Get勤務日by打刻日時(touch, spec);

3.ビジネスロジックの置き場所に困った時は「仕様パターン」!

勤務日仕様

勤務日仕様(TimeSpan)IsSatisfy(勤務日, 打刻日時)

勤務日勤務日Repository

FindBy打刻日時(打刻日時,勤務日仕様)

復元

Add(打刻日時)

打刻日時*

Factory

Factory(打刻日時,勤務日仕様)

Create()

生成

.NET 編

ソフトウェアアーキテクチャ実装

ソフトウェアアーキテクチャ実装

全体構成の概要

presentation

infrastructure

勤怠管理.Web

勤怠管理.Infrastructure

domain

interfaces

application

domain

勤怠管理

interfaces

application

domain

Web, WebAPI

ソフトウェアアーキテクチャ実装

interfaces ー 外部とDomainとの連携をとりもつ

サンプル

interfaces<usecase1>

<usecase2>

facade

dto

inner

converter

ISampleServiceFacade

SampleServiceFacadeImpl

SampleModelDTO

SampleModelConverter

≪public≫

アクセス修飾子がpublicなのはfaçadeのインターフェースとDTOの2種類だけで、他はすべて外部からは見えないアクセス修飾子(C#ならinternal)にします。

Interfacesフォルダの直下に作成するフォルダはユースケース単位となります。

presentation

infrastructure

domain

interfaces

application

domain

Web, WebAPI

Interfaceは、domain外部との境界です。外部よりプリミティブ型を受け取り、モデルに変換します。変換したモデルをApplicationServicesに渡し、ビジネスロジックを起動します。ApplicationServicesからの戻り値を外部へ返却する場合は、DTOに変換してから渡すのも役目の1つです。

≪public≫

ソフトウェアアーキテクチャ実装application ー ルートエンティティを扱う

サンプル

application

ISampleAService

impl

SampleAServiceImpl

domainmodel

sampleA

aggregate

SampleA

ISampleARepository

SampleAEvent

application中のクラスのアクセス修飾子はすべてinternalです。

applicationで実装するサービスは、Repositoryの具象クラスをDIContainerから受け取ります。

presentation

infrastructure

domain

interfaces

application

domain

Web, WebAPI

applicationはinterfacesからのみ、起動します。applicationはinterfacesと1:1にします。(元々、interfacesは存在しません。interfacesの役割もapplicationで実装するのですが、処理が煩雑すぎるので分割したのです。)

applicationのメインの役割は、ビジネスロジックを起動です。そのための具体的な実装は以下になります。・ルートエンティティの生成・保管・復元・ルートエンティティのロジックの起動・ドメインイベントのレイズ1つのapplicationは複数のルートエンティティを扱います。

≪internal≫

sampleA…集約SampleA…ルートエンティティ

≪internal≫

ソフトウェアアーキテクチャ実装domain ー ビジネスロジック

サンプル

domainmodel

sampleA

service

shared

sampleB

SampleA

ISampleARepositorySampleIdSampleA.InnerModelA

IEntityIEntityIdentifier

IValueObject

SampleService

IDomainEvent

SampleAEvent

domainの中には「model、service、shared」の3つフォルダを作成しておきます。modelの中は、さらに集約単位でフォルダを作成します。フォルダ名には集約ルートクラス名を「先頭小文字」で付けます。

domainの中のクラスのアクセス修飾子はすべてinternalです。集約の中に作るIRepositoryもinternalです。

Repositoryの実装はdomainでは行いません。infrastructureで行います。

.NETの場合、IRepositoryがこのままではInfrastructureからみえないので、AssemblyInfo.csにてInternalVisibleTo属性を使用してinternalをinfrastructureに公開します。

≪internal≫presentation

infrastructure

domain

interfaces

application

domain

Web, WebAPI

sampleA→集約

SampleA→ルートエンティティ

ISampleARepository→ルートエンティティに対

するリポジトリ

SampleId→エンティティのIdバ

リューオブジェクト

InnerModelA→集約内部に隠れているバ

リューオブジェクト

SampleAEvent→ドメインイベント

ソフトウェアアーキテクチャ実装

infrastrucute – 外部との通信サンプル

domainmodel

sampleA

SampleA

ISampleARepository

SampleAEvent

infrastructure

messaging

persistenceSampleAEventPublisher

SampleARepository

queue

dapper

≪internal≫presentation

infrastructure

domain

interfaces

application

domain

Web, WebAPI

infrastructureではdomainで宣言されたIRepositoryと、DomainEventの実装を行います。

Database Queue Service

ソフトウェアアーキテクチャ実装

おすすめのサンプル

DDDSample Java DDD本の内容を実際に作ってみたサンプル。定番?一度は見ておく必要あり。https://github.com/citerus/dddsample-core

IDDD_Sample Java 実践DDD本の内容を実際に作ったサンプル。著者であるVaughn Vernonが本の内容に沿って自ら作ったものらしい。境界づけられたコンテキスト,EventSourcing, CQRSの実例を見たいならこれ。https://github.com/VaughnVernon/IDDD_Samples

IDDD_Sample_NET C# IDDD_SampleのC#版。

Domain-Driven-Design-Example

C# ドメインイベント、Specificationの実例あり。解説が全部英語なのはちょっと辛い。https://github.com/zkavtaskin/Domain-Driven-Design-Example

AzureとDDD

AzureとDDD

DDDでは、ドメインイベントが非同期処理の対象となりやすい

EventSourcingやCQRSと組み合わせやすい

applicationinterface

Messaging

Aggregate

EventFactoryEvent

EventPublisher

Service Bus Queue

Storage Queue

Persistence

IRepository

SQL Database

コマンド

クエリ

SQL DatabaseDataAccess

Web Job

CQRSの例

domain

Section 1/1 total 13/13

非同期処理パターンの実現をAzureで

EventSourcingの例

Web JobSQL Database

Publisher

Azure ServiceFabric と DDD

Azure Service FabricとDDD

ServiceFabricのご紹介

ServiceFabricとは、大きく分けて2つの機能を持ちます。

1.Reliable Service

自分でPaaSを構築するためのインフラ

2.Reliable Actor

Actorパターンを実現するためのPaaS

DDDに直接関係があるのは2の方です。

今日は2のActorパターンの実現についてご紹介します。

ActorパターンとDDD

出典:InfoQ Vaughn Vernon氏が語る、アクターモデルとドメイン駆動設計https://www.infoq.com/jp/news/2013/06/actor-model-ddd

Actorパターン(モデル)とは

Actorパターンの特徴• 他のActorにメッセージを送信します。

• 送信元のActorは、メッセージの受信を待たずに次の処理をします。(非同期的な動作)

• どのActorにメッセージを送信するのかは、アドレスで指定します。

• メッセージ送信の順に受信することは保証されません。(順不同)

• Actorは他のActorを生成することができます。(Child Actor)

• Actor間で状態の共有はありません。

出典:Wikipedia https://ja.wikipedia.org/wikiアクターモデル

Actor Actor

Reliable Actor(Service Fabric)

その特徴

仮想Actor

Actorオブジェクトは、メモリ内表現と直接関連付けられていません。Actorオブジェクトは、Webサービスのようなもので、その生成と破棄を意識する必要がありません。

Reliable Actorプラットフォームは、メッセージが着信するとActorオブジェクトを自動的に生成します。

一定期間メッセージの着信がないと、Actorオブジェクトは破棄されます。その際、Actorオブジェクトの状態は自動的に保存されます。

同時実行

Actorオブジェクトはシングルスレッドで稼働します。そのため、複数のメッセージ着信があったとしても、同時に処理が動くことはありません。

Actorとの通信

ActorはInterfaceを公開し、実装はそのInterfaceをimplementsする形式となります。Actorを呼び出すクライアントはそのインターフェースを使って通信用のProxyオブジェクトを生成し、Actorオブジェクトのメソッドを叩きます。アドレスの指定はありません。(※どのFabricアプリケーションにデプロイされているかを指定する必要はあります)

Actorのメソッドを叩くときの引数にセットするオブジェクトはシリアライズ可能である必要があります。

Reliable Actor(Service Fabric)

実装時イメージ

IActor

IMyActor

MyActor

<<abstract>>Actor ActorProxy

Actor側 Client側

Actorを実装するためには、必ずServcieFabricSDKで用意されているIActorインターフェースを継承した自前のインターフェースを宣言する必要があります。(IMyActor)

さらにActorの具象クラスはServieFabricのSDKで用意されているActor抽象クラスを継承します。(MyActor)

Reliable Actor(Service Fabric)ActorでHelloworldする

Visual Studio のテンプレートでActorを選択して作成

Reliable Actor(Service Fabric)ActorでHelloworldする

namespace HelloWorldActor.Interfaces{

public interface IHelloWorldActor : IActor{

Task<int> GetCountAsync();

Task SetCountAsync(int count);

Task<string> HelloWorldAsync(); }

}

非同期処理なので、Task型を返却。文字列を返却する場合はGenericでstringを指定

Reliable Actor(Service Fabric)

Hello World文字列を返却します。Task型を返却する必要があるので、Task.FromResultメソッドを利用します。

ActorでHelloworldする

namespace HelloWorldActor{

[StatePersistence(StatePersistence.Persisted)]internal class HelloWorldActor : Actor, IHelloWorldActor{

public HelloWorldActor(ActorService actorService, ActorId actorId): base(actorService, actorId)

{}

・・・

Task IHelloWorldActor.SetCountAsync(int count){

・・・}

Task<string> IHelloWorldActor.HelloWorldAsync(){

return Task.FromResult("Hello World!");}

}}

Reliable Actor(Service Fabric)

Clientを実装します。ServiceFabricとしてプロジェクトをまとめている「ServiceFabric

Helloworldプロジェクト」を右クリックして追加します。

ActorでHelloworldする

Reliable Actor(Service Fabric)

ステートレス

Web APIを選択します。

このテンプレートは一番左のステートレスサービスを選択した後に、WebAPI用のライブラリをインストールしてセットアップしてあるものです。

ActorでHelloworldする

Reliable Actor(Service Fabric)

ActorProxy.Createで生成したプロキシオブジェクトを使用して、HelloWorldAsyncメソッドを叩いています。

ActorでHelloworldする

namespace WebApi.Controllers{

[ServiceRequestActionFilter]public class HelloworldController : ApiController{

private static Uri serviceUri =new Uri("fabric:/ServiceFabricHelloworld/HelloWorldActorService");

private static ActorId actorId = ActorId.CreateRandom();private static IHelloWorldActor helloworldActor =

ActorProxy.Create<IHelloWorldActor>(actorId, serviceUri);

// GET api/values public IEnumerable<string> Get(){

string greetings = helloworldActor.HelloWorldAsync().Result;

return new string[] { greetings };}

・・・}

}

Reliable Actor(Service Fabric)

結果

ActorでHelloworldする

ありがとうございました