CDSのプラグインで事前バインドを行う

完全に車輪の再発明ですが。

## 前提
- OSはWindows 10です
- PowerShell 7はクロスプラットフォームなので、CRM SDKの取得までは、PowerShell7ならばMac OSやLinuxでもできるはず
- でも、Mac OSやLinuxだとCrmSvcUtil.exeが動かないと思う
- たしかめてはいない
- 日本語と英語が混在しているが、気にしないでほしい
- 生成したクラスの使い方は別途記事にします

## 事前バインドとは
CDSのプラグインを開発して、レコードを作成したり更新したりする場合に2つのやり方があります]

 - 事前バインド
    - エンティティのメタデータに基づいて、ツールでクラスを生成する
    - 生成したクラスを使って、コーディングする
 - 遅延バインド
    - エンティティのメタデータのLogicalNameを使用してコーディングする


メリット・デメリットの詳細は以下のDocsにまとまっています。

https://docs.microsoft.com/ja-jp/powerapps/developer/common-data-service/org-service/early-bound-programming

しかし、基本的には、事前バインドを使った方がよいです。
遅延バインドはクラスを生成しなくともすむので手軽なのですが、コンパイルエラーにならないので、デバッグやテストが辛いです。
エンティティの定義もソースで確認できて、CDSの画面やドキュメントを書くしないですむので、
コーディングスピードも上がると思います。

## CrmSvcUtil.exeの使い方
事前バインドのためのクラスを生成してくれるツールがCrmSvcUtil.exeです。
本記事では、このツールの使い方の一例を記載します。

他にもいろいろなことができるので、Docsをみてください。
https://docs.microsoft.com/ja-jp/powerapps/developer/common-data-service/org-service/generate-early-bound-classes

### 組織サービスのエンドポイントの取得
1. 環境を選択し、歯車のマークをクリックし、詳細設定をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287381/46e70174-d9fb-17fe-fad8-e290a3b8cb07.png)
1. Settingsの下向きの「>」をクリックし、Customizationsをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287381/2c09d2f5-1b79-556e-616a-b12c39656e1e.png)
1. Developper Resourcesをクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287381/a2290d84-50f1-96fd-dc42-dca7a39de96b.png)
1. Organization ServiceのEndpointをコピー
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287381/8cc941d0-1608-4ac2-a13f-8fc1fd52167b.png)

### CRM SDKのダウンロード・configファイルの編集
1. PowerShellでCRM SDKをダウンロードする
    - 以下のページにあるコマンドを叩く
        - https://docs.microsoft.com/ja-jp/powerapps/developer/common-data-service/download-tools-nuget
        - 上の手順にもありますが、新しくフォルダを切った方がよいです
        - CRM SDKで検索すると、v8.xのCRM SDKがダウンロードできるページがでてきますが、最新版は上ページのコマンドで取得できます
1. CrmSvcUtil.exeが格納されているフォルダを開く
    - C:\PowerAppsDevToolsで1.のコマンドを実行した場合は以下 
        - C:\PowerAppsDevTools\Tools\Microsoft.CrmSdk.CoreTools.x.x.x.xx\content\bin\coretools
        - Microsoft.CrmSdk.CoreTools.x.x.x.xxのxはSDKのバージョンになる
1. 2.のフォルダに格納されているCrmSvcUtil.exe.configを開く
1. CrmSvcUtil.exe.configを編集して保存する

#### Before
```xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="MaxCrmConnectionTimeOutMinutes" value="20"/>
  </appSettings>
```
#### After
``` xml
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <appSettings>
    <add key="MaxCrmConnectionTimeOutMinutes" value="20"/>
    <add key="url" value="YourUrl"/>
    <add key="o" value="C:\PowerAppsDevTools\MyCode\EntityDefinition.cs"/>
    <add key="u" value="YourUser@YourOrganization.onmicrosoft.com"/>
    <add key="p" value="YourPassword"/>
  </appSettings>
```  
 - urlは「組織サービスのエンドポイントの取得」の4.で取得したURL
 - oは生成したクラスの名前(絶対パスでフォルダも指定できます)
    - ただし、フォルダは事前に作成していないと実行時にエラーになる
 - uはユーザー名、認証を通すユーザーのメールアドレス
 - pはuのパスワード
 - ホントはnで、名前空間も指定した方がいいかな
 - **DocsにはURLパラメータは指定しないように書いてあるけど、その心がよくわからなかった**
    - https://docs.microsoft.com/ja-jp/powerapps/developer/common-data-service/org-service/generate-early-bound-classes
 
### CrmSvcUtil.exeの実行
1. コマンドプロンプトを起動
    - PowerShellではダメ
1. 「CRM SDKのダウンロード・configファイルの編集」の2.のフォルダに移動
1. CrmSvcUtil.exeを実行
1. 「CRM SDKのダウンロード・configファイルの編集」の4.のoに指定したフォルダ・名前でクラスが生成される

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287381/0ecbfd74-1785-d658-3226-ebd22dd64068.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/287381/f88bcd1c-44af-7368-25e6-7071efe1d35a.png)