AssemblyDefinitionは、参照元もリコンパイルされてしまう

エディタリフレッシュの際のコンパイルだけで1分くらい待たされるプロジェクトを触っています。処理待ちという無駄な時間が増えるばかりではなく、脳内のキャッシュは切れてしまい、コンパイルが面倒くさいからと動作確認をおろそかにしてしまいがちになってしまいます。

ちょっとでもこの時間を短くしたいのですが、普段書いているゲームロジックコードを参照するエディタ拡張やライブラリ（！？）が蔓延っており、適当に参照を切っていくだけではあまり早くなりませんでした。

よくよく調べてみると、リコンパイルをスキップするアセンブリが少なくなっていました。

# TL;DR;

変更したファイルのアセンブリをリコンパイル、およびリコンパイルしたアセンブリに依存するアセンブリをリコンパイルする。

# 実証

## 編集したファイルのアセンブリだけリコンパイル

Assets
└ Asm1
　└ Asm1.assemdef
　└ Asm1.cs
└ Asm2
　└ Asm2.assemdef
　└ Asm2.cs

Asm2.csを編集

```yaml
Refresh: detecting if any assets need to be imported or removed ...

Hashing assets (1 files)... 0.000 seconds
  file read: 0.000 seconds (0.000 MB)
  wait for write: 0.000 seconds (I/O thread blocked by consumer, aka CPU bound)
  wait for read: 0.000 seconds (CPUT thread waiting for I/O thread, aka disk bound)
  hash: 0.000 seconds
----- Compute hash(es) for 1 asset(s).

Refresh: elapses 0.052906 seconds
Updating Assets/Asm2/Asm2.cs - GUID: 3c91f26a61b4c6c45aab574fa4f75298...
 done. [Time: 40.415700 ms] 
Refreshing native plugins compatible for Editor in 0.58 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.24 ms.

----- Total AssetImport time: 0.171247s, AssetImport time: 0.102776s, Asset hashing: 0.000623s [500 B, 0.765757 mb/s]

Refresh completed in 0.180299 seconds.
- Starting compile Library/ScriptAssemblies/Asm2.dll
- Finished compile Library/ScriptAssemblies/Asm2.dll
Symbols will be read from Temp\Asm2.dll.mdb
Script Module: Asm2.dll
Pass: 0 took 3 milliseconds
Pass: 1 took 2 milliseconds
Reloading assemblies after finishing script compilation.
Begin MonoManager ReloadAssembly
Initializing Unity.PackageManager (PackageManager) v2018.2.14 for Unity v2018.2.14f1
Registering platform support modules:
Registered platform support modules in: 0.0291521s.
Native extension for WindowsStandalone target not found
Refreshing native plugins compatible for Editor in 0.63 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.25 ms.
Mono: successfully reloaded assembly
Refreshing native plugins compatible for Editor in 0.60 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.28 ms.

----- Total AssetImport time: 0.111033s, AssetImport time: 0.000000s, Asset hashing: 0.000000s [0 B, 0.000000 mb/s]
```

## 編集したファイルのアセンブリだけリコンパイル

Assets
└ Asm1
　└ Asm1.assemdef
　└ Asm1.cs
　└ Asm2
　　└ Asm2.assemdef
　　└ Asm2.cs

Asm2.csを編集

```yaml
Refresh: detecting if any assets need to be imported or removed ...

Hashing assets (1 files)... 0.000 seconds
  file read: 0.000 seconds (0.000 MB)
  wait for write: 0.000 seconds (I/O thread blocked by consumer, aka CPU bound)
  wait for read: 0.000 seconds (CPUT thread waiting for I/O thread, aka disk bound)
  hash: 0.000 seconds
----- Compute hash(es) for 1 asset(s).

Refresh: elapses 0.060080 seconds
Updating Assets/Asm1/Asm2/Asm2.cs - GUID: 3c91f26a61b4c6c45aab574fa4f75298...
 done. [Time: 41.909700 ms] 
Refreshing native plugins compatible for Editor in 0.58 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.24 ms.

----- Total AssetImport time: 0.179372s, AssetImport time: 0.106449s, Asset hashing: 0.000634s [498 B, 0.748864 mb/s]

Refresh completed in 0.190342 seconds.
- Starting compile Library/ScriptAssemblies/Asm2.dll
- Finished compile Library/ScriptAssemblies/Asm2.dll
Symbols will be read from Temp\Asm2.dll.mdb
Script Module: Asm2.dll
Pass: 0 took 3 milliseconds
Pass: 1 took 2 milliseconds
Reloading assemblies after finishing script compilation.
Begin MonoManager ReloadAssembly
Initializing Unity.PackageManager (PackageManager) v2018.2.14 for Unity v2018.2.14f1
Registering platform support modules:
Registered platform support modules in: 0.0280922s.
Native extension for WindowsStandalone target not found
Refreshing native plugins compatible for Editor in 0.62 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.26 ms.
Mono: successfully reloaded assembly
Refreshing native plugins compatible for Editor in 0.59 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.27 ms.

----- Total AssetImport time: 0.108809s, AssetImport time: 0.000000s, Asset hashing: 0.000000s [0 B, 0.000000 mb/s]
```

## 両方リコンパイル

Assets
└ Asm1 ------------------> Asm2を参照
　└ Asm1.assemdef
　└ Asm1.cs
└ Asm2
　└ Asm2.assemdef
　└ Asm2.cs

Asm2.csを編集

```yaml
Refresh: detecting if any assets need to be imported or removed ...

Hashing assets (1 files)... 0.000 seconds
  file read: 0.000 seconds (0.000 MB)
  wait for write: 0.000 seconds (I/O thread blocked by consumer, aka CPU bound)
  wait for read: 0.000 seconds (CPUT thread waiting for I/O thread, aka disk bound)
  hash: 0.000 seconds
----- Compute hash(es) for 1 asset(s).

Refresh: elapses 0.053719 seconds
Updating Assets/Asm2/Asm2.cs - GUID: 3c91f26a61b4c6c45aab574fa4f75298...
 done. [Time: 41.711300 ms] 
Refreshing native plugins compatible for Editor in 0.58 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.23 ms.

----- Total AssetImport time: 0.181877s, AssetImport time: 0.110376s, Asset hashing: 0.000650s [501 B, 0.735289 mb/s]

Refresh completed in 0.191066 seconds.
- Starting compile Library/ScriptAssemblies/Asm2.dll
- Finished compile Library/ScriptAssemblies/Asm2.dll
Symbols will be read from Temp\Asm2.dll.mdb
Script Module: Asm2.dll
Pass: 0 took 9 milliseconds
Pass: 1 took 2 milliseconds
- Starting compile Library/ScriptAssemblies/Asm1.dll
- Finished compile Library/ScriptAssemblies/Asm1.dll
Symbols will be read from Temp\Asm1.dll.mdb
Script Module: Asm1.dll
Pass: 0 took 2 milliseconds
Pass: 1 took 0 milliseconds
Reloading assemblies after finishing script compilation.
Begin MonoManager ReloadAssembly
Initializing Unity.PackageManager (PackageManager) v2018.2.14 for Unity v2018.2.14f1
Registering platform support modules:
Registered platform support modules in: 0.0291168s.
Native extension for WindowsStandalone target not found
Refreshing native plugins compatible for Editor in 0.62 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.24 ms.
Mono: successfully reloaded assembly
Refreshing native plugins compatible for Editor in 0.74 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.27 ms.

----- Total AssetImport time: 0.109616s, AssetImport time: 0.000000s, Asset hashing: 0.000000s [0 B, 0.000000 mb/s]
```

そりゃあそうです。基本的にコンパイルをする際には、リンクするアセンブリが必要です。リンクされているたアセンブリが変わってしまったのならば、リンクしているアセンブリもコンパイルが必要になります。

## 編集したファイルのアセンブリだけリコンパイル

Assets
└ Asm1
　└ Asm1.assemdef
　└ Asm1.cs
└ Asm2 ------------------> Asm1を参照
　└ Asm2.assemdef
　└ Asm2.cs

Asm2.csを編集

```yaml
Refresh: detecting if any assets need to be imported or removed ...

Hashing assets (1 files)... 0.001 seconds
  file read: 0.000 seconds (0.000 MB)
  wait for write: 0.000 seconds (I/O thread blocked by consumer, aka CPU bound)
  wait for read: 0.000 seconds (CPUT thread waiting for I/O thread, aka disk bound)
  hash: 0.000 seconds
----- Compute hash(es) for 1 asset(s).

Refresh: elapses 0.051379 seconds
Updating Assets/Asm2/Asm2.cs - GUID: 3c91f26a61b4c6c45aab574fa4f75298...
 done. [Time: 41.469600 ms] 
Refreshing native plugins compatible for Editor in 0.61 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.27 ms.

----- Total AssetImport time: 0.180083s, AssetImport time: 0.111637s, Asset hashing: 0.000786s [502 B, 0.608935 mb/s]

Refresh completed in 0.189812 seconds.
- Starting compile Library/ScriptAssemblies/Asm2.dll
- Finished compile Library/ScriptAssemblies/Asm2.dll
Symbols will be read from Temp\Asm2.dll.mdb
Script Module: Asm2.dll
Pass: 0 took 9 milliseconds
Pass: 1 took 2 milliseconds
Reloading assemblies after finishing script compilation.
Begin MonoManager ReloadAssembly
Initializing Unity.PackageManager (PackageManager) v2018.2.14 for Unity v2018.2.14f1
Registering platform support modules:
Registered platform support modules in: 0.0281124s.
Native extension for WindowsStandalone target not found
Refreshing native plugins compatible for Editor in 0.62 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.25 ms.
Mono: successfully reloaded assembly
Refreshing native plugins compatible for Editor in 0.61 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.28 ms.

----- Total AssetImport time: 0.136121s, AssetImport time: 0.000000s, Asset hashing: 0.000000s [0 B, 0.000000 mb/s]
```



## 編集したファイルのアセンブリだけリコンパイル

Assets
└ Asm0.cs
└ Asm1
　└ Asm1.assemdef
　└ Asm1.cs
└ Asm2
　└ Asm2.assemdef
　└ Asm2.cs

Asm0.csを編集

```yaml
Refresh: detecting if any assets need to be imported or removed ...

Hashing assets (1 files)... 0.000 seconds
  file read: 0.000 seconds (0.000 MB)
  wait for write: 0.000 seconds (I/O thread blocked by consumer, aka CPU bound)
  wait for read: 0.000 seconds (CPUT thread waiting for I/O thread, aka disk bound)
  hash: 0.000 seconds
----- Compute hash(es) for 1 asset(s).

Refresh: elapses 0.053115 seconds
Updating Assets/Asm0.cs - GUID: e88de36ee2d313c4cada56d80313fcdd...
 done. [Time: 65.020100 ms] 
Refreshing native plugins compatible for Editor in 0.59 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.24 ms.

----- Total AssetImport time: 0.201773s, AssetImport time: 0.133642s, Asset hashing: 0.000656s [499 B, 0.725653 mb/s]

Refresh completed in 0.210796 seconds.
- Starting compile Library/ScriptAssemblies/Assembly-CSharp.dll
- Finished compile Library/ScriptAssemblies/Assembly-CSharp.dll
Symbols will be read from Temp\Assembly-CSharp.dll.mdb
Script Module: Assembly-CSharp.dll
Pass: 0 took 3 milliseconds
Pass: 1 took 2 milliseconds
Reloading assemblies after finishing script compilation.
Begin MonoManager ReloadAssembly
Initializing Unity.PackageManager (PackageManager) v2018.2.14 for Unity v2018.2.14f1
Registering platform support modules:
Registered platform support modules in: 0.0283626s.
Native extension for WindowsStandalone target not found
Refreshing native plugins compatible for Editor in 0.64 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.26 ms.
Mono: successfully reloaded assembly
Refreshing native plugins compatible for Editor in 0.58 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.28 ms.

----- Total AssetImport time: 0.112545s, AssetImport time: 0.000000s, Asset hashing: 0.000000s [0 B, 0.000000 mb/s]
```

## 編集したファイルのアセンブリだけリコンパイル

Assets
└ Asm0.cs
└ Asm1
　└ Asm1.assemdef
　└ Asm1.cs
└ Asm2 ------------------> Asm1を参照
　└ Asm2.assemdef
　└ Asm2.cs

Asm2.csを編集

```yaml
Refresh: detecting if any assets need to be imported or removed ...

Hashing assets (1 files)... 0.001 seconds
  file read: 0.000 seconds (0.000 MB)
  wait for write: 0.000 seconds (I/O thread blocked by consumer, aka CPU bound)
  wait for read: 0.000 seconds (CPUT thread waiting for I/O thread, aka disk bound)
  hash: 0.000 seconds
----- Compute hash(es) for 1 asset(s).

Refresh: elapses 0.053522 seconds
Updating Assets/Asm2/Asm2.cs - GUID: 3c91f26a61b4c6c45aab574fa4f75298...
 done. [Time: 41.507900 ms] 
Refreshing native plugins compatible for Editor in 0.59 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.24 ms.

----- Total AssetImport time: 0.181404s, AssetImport time: 0.108466s, Asset hashing: 0.000719s [503 B, 0.666989 mb/s]

Refresh completed in 0.190450 seconds.
- Starting compile Library/ScriptAssemblies/Asm2.dll
- Finished compile Library/ScriptAssemblies/Asm2.dll
Symbols will be read from Temp\Asm2.dll.mdb
Script Module: Asm2.dll
Pass: 0 took 3 milliseconds
Pass: 1 took 6 milliseconds
- Starting compile Library/ScriptAssemblies/Assembly-CSharp.dll
- Finished compile Library/ScriptAssemblies/Assembly-CSharp.dll
Symbols will be read from Temp\Assembly-CSharp.dll.mdb
Script Module: Assembly-CSharp.dll
Pass: 0 took 7 milliseconds
Pass: 1 took 0 milliseconds
Reloading assemblies after finishing script compilation.
Begin MonoManager ReloadAssembly
Initializing Unity.PackageManager (PackageManager) v2018.2.14 for Unity v2018.2.14f1
Registering platform support modules:
Registered platform support modules in: 0.0294676s.
Native extension for WindowsStandalone target not found
Refreshing native plugins compatible for Editor in 0.62 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.25 ms.
Mono: successfully reloaded assembly
Refreshing native plugins compatible for Editor in 0.61 ms, found 11 plugins.
Preloading 3 native plugins for Editor in 0.28 ms.

----- Total AssetImport time: 0.137557s, AssetImport time: 0.000000s, Asset hashing: 0.000000s [0 B, 0.000000 mb/s]
```

Assembly-CSharpは自動で、すべてのアセンブリにリンクされます、依存しています。

# 無理矢理相互参照を排除する

基本的にはインターフェイスなどで宣言と実装を分けて実装を別アセンブリに分ける方法をとっていくことおもいます。しかし、リフレクションで名前でアクセスすることで、実質参照していないことになり相互参照を解除することができます！（もちろん名前が変わった瞬間例外発生！！）

```cs:Asm1.cs
public class Asm1 : MonoBehaviour
{
	void Start()
	{
		Assembly asm = Assembly.Load("Asm2");
		Type type = asm.GetType("Asm2", true);
		object instance = type.GetField("I").GetValue(null);
		object text = type.GetField("field").GetValue(instance);
		UnityEngine.Debug.Log(text);
	}
}
```

```cs:Asm2.cs
/// <summary>
/// 諸悪の根源シングルトン！
/// </summary>
public class Asm2 : MonoBehaviour
{
	public static Asm2 I;
	public string field = "Hoge";

	void Awake()
	{
		I = this;
	}
}
```

Asm1.csとAsm2.csが別のアセンブリになっていてもこれで値を取り出し、メソッドをひっぱたくことができます。保守性は最悪ですが、コンパイル時間が大幅に短縮できるのであれば背に腹は代えられないかもしれません。