Skip to content

Commit

Permalink
Merge pull request #912 from Cysharp/feature/UpdateDocs25020401
Browse files Browse the repository at this point in the history
Update documents
  • Loading branch information
mayuki authored Feb 4, 2025
2 parents e291bee + 7848d85 commit 27e1528
Show file tree
Hide file tree
Showing 9 changed files with 393 additions and 5 deletions.
161 changes: 161 additions & 0 deletions docs/docs/fundamentals/project-structure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,161 @@
# Project Structure

This page describes the recommended project structure for projects using MagicOnion.

.NET applications typically consist of a large unit called a solution, which contains .NET projects such as applications and libraries.
Applications using MagicOnion typically have a server and client project, and are configured to share interfaces through some means.

## Typical structure of a .NET application

Here is an example of a typical project (solution) structure for a .NET application (console app, WPF or .NET MAUI etc).

- **MyApp.sln**: Solution file
- **MyApp.Server**: MagicOnion server application (ASP.NET Core gRPC Server)
- This project provides MagicOnion APIs and processes requests from clients
- **MyApp.Client**: MagicOnion client application (Console, WPF, WinForms, .NET MAUI, etc...)
- This project connects to the MagicOnion server and sends requests
- **MyApp.Shared**: Shared interface library (.NET library project)
- This project contains interface definitions for MagicOnion, such as Hub and Service interface definitions, MessagePack types used in requests/responses, etc.

:::note
Replace `MyApp` with your project name or solution name.
:::

The following is an example of directory structure for the above project structure.

```plaintext
MyApp.sln
|─ src
| ├─ MyApp.Server
| │ ├─ MyApp.Server.csproj
| | ├─ Hubs
| | | ├─ ChatHub.cs
| | └─ Services
| | └─ GreeterService.cs
| ├─ MyApp.Client
| │ ├─ MyApp.Client.csproj
| │ └─ Program.cs
| └─ MyApp.Shared
| ├─ MyApp.Shared.csproj
| ├─ Hubs
| | ├─ IChatHub.cs
| |─ Services
| | └─ IGreeterService.cs
| |─ Requests
| | └─ HelloRequest.cs
| └─ Responses
| └─ HelloResponse.cs
└─ test
└─ MyApp.Server.Test
└─ ...
```

`MyApp.Shared` project is created as a .NET class library, references the `MagicOnion.Abstractions` package, and defines only pure interface definitions, data types, and enum types.
And the `MyApp.Server` and `MyApp.Client` projects share interfaces by referencing the `MyApp.Shared` project.

This is a minimal configuration example, and in actual projects, you may have projects or hierarchies such as models, domains, and ViewModels as needed.

## Unity application structure

Here is an example of a project structure for sharing interfaces between Unity client and server projects.

The structure of a Unity application is different from a typical .NET project in that Unity projects cannot reference .NET library projects.
This is because Unity projects cannot reference .NET library projects.

The recommended configuration is as follows:

- **MyApp.Server.sln**: Solution file
- **MyApp.Server**: MagicOnion server application (ASP.NET Core gRPC Server)
- **MyApp.Unity**: Unity client application
- **MyApp.Shared**: Shared interface library (.NET library project and Unity local package)

```plaintext
MyApp.Server.sln
|─ src
| ├─ MyApp.Server
| │ ├─ MyApp.Server.csproj
| │ ├─ Program.cs
| │ ├─ Hubs
| │ │ └─ ChatHub.cs
| │ └─ Services
| │ └─ GreeterHub.cs
| ├─ MyApp.Shared
| │ ├─ MyApp.Shared.csproj
| │ ├─ package.json
| │ ├─ Hubs
| │ │ └─ IChatHub.cs
| │ └─ Services
| │ └─ IGreeterHub.cs
| └─ MyApp.Unity
| ├─ Assembly-CSharp.csproj
| ├─ MyApp.Unity.sln
| └─ Assets
| └─ ...
└─ test
└─ MyApp.Server.Test
└─ ...
```

`MyApp.Shared` project is created as a .NET class library, references the `MagicOnion.Abstractions` package, and defines only pure interface definitions, data types, and enum types.
In addition, it includes a `package.json` to make it available to Unity projects via the Unity Package Manager, and is configured not to output folders such as `bin` and `obj`.

Here is an example of a minimal `package.json` file for a Unity local package.

```json
{
"name": "com.cysharp.magiconion.samples.myapp.shared.unity",
"version": "1.0.0",
"displayName": "MyApp.Shared.Unity",
"description": "MyApp.Shared.Unity",
}
```

We recommend creating a `MyApp.Shared.Unity.asmdef` (Assembly Definition) file to define the Unity-specific assembly and to avoid naming conflicts with `MyApp.Shared`. Be careful not to use the same name as `MyApp.Shared` by adding a `.Unity` suffix, for example.

Next, add the following settings to `MyApp.Shared.csproj` to prevent the creation of `bin` and `obj` directories and to hide Unity-specific files from the IDE.

```xml
<PropertyGroup>
<!-- https://learn.microsoft.com/en-us/dotnet/core/sdk/artifacts-output -->
<ArtifactsPath>$(MSBuildThisFileDirectory).artifacts</ArtifactsPath>
</PropertyGroup>

<!-- Hide Unity-specific files from Visual Studio and .NET SDK -->
<ItemGroup>
<None Remove="**\package.json" />
<None Remove="**\*.asmdef" />
<None Remove="**\*.meta" />
</ItemGroup>

<!-- Hide build artifacts from Visual Studio and .NET SDK -->
<ItemGroup>
<None Remove=".artifacts\**\**.*" />
<None Remove="obj\**\*.*;bin\**\*.*" />
<Compile Remove=".artifacts\**\**.*" />
<Compile Remove="bin\**\*.*;obj\**\*.*" />
<EmbeddedResource Remove=".artifacts\**\**.*" />
<EmbeddedResource Remove="bin\**\*.*;obj\**\*.*" />
</ItemGroup>
```

With this configuration, intermediate files and built files are output to `.artifacts`, so if `bin` and `obj` directories are created, delete them.

Next, add a reference to `MyApp.Shared` in the Unity project's `Packages/manifest.json`.

```json
{
"dependencies": {
"com.cysharp.magiconion.samples.myapp.shared.unity": "file:../MyApp.Shared/MyApp.Shared.Unity"
}
}
```

`MyApp.Server` project references the `MyApp.Shared` project to share interfaces. This is similar to a typical .NET application.

### Merging solutions with SlnMerge

By using [SlnMerge](https://github.com/Cysharp/SlnMerge), you can merge the solutions generated by Unity and .NET projects.

For example, MyApp.Server.sln contains MyApp.Server and MyApp.Shared projects, but the solution generated by Unity contains only Unity projects (Assembly-CSharp, Assembly-CSharp-Editor, etc.). By using SlnMerge, you can merge these solutions so that the server project can be seamlessly referenced even when the solution is opened from Unity.

This allows for reference searches and debugger step-ins between Unity and .NET projects, which can improve development experiences.
6 changes: 6 additions & 0 deletions docs/docs/support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Support
MagicOnion provides community-based support. Please use the following resources.

- [GitHub Issues](https://github.com/Cysharp/MagicOnion/issues)

Please report bugs, feature requests, questions, and other issues here. Community support does not guarantee response times or feature requests.
12 changes: 9 additions & 3 deletions docs/docusaurus.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,16 +51,16 @@ const config: Config = {
routeBasePath: '/',

sidebarPath: './sidebars.ts',
sidebarCollapsed: false,
sidebarCollapsed: true,

showLastUpdateTime: true,

editUrl: (params) => params.locale == 'en'
? `https://github.com/Cysharp/MagicOnion/tree/main/docs/docs/${params.docPath}`
: `https://github.com/Cysharp/MagicOnion/tree/main/docs/i18n/${params.locale}/docusaurus-plugin-content-docs/current/${params.docPath}`,

remarkPlugins: [additionalHeaderMetaRow],
},
remarkPlugins: [additionalHeaderMetaRow],
},
theme: {
customCss: './src/css/custom.css',
},
Expand Down Expand Up @@ -91,6 +91,12 @@ const config: Config = {
label: 'License',
docId: 'license',
},
{
type: 'doc',
position: 'left',
label: 'Support',
docId: 'support',
},
{
href: 'https://cysharp.co.jp/en/',
label: 'Cysharp, Inc.',
Expand Down
4 changes: 4 additions & 0 deletions docs/i18n/ja/docusaurus-plugin-content-docs/current.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,10 @@
"message": "インテグレーション",
"description": "The label for category Integration in sidebar docsSidebar"
},
"sidebar.docsSidebar.category.Best practices": {
"message": "ベストプラクティス",
"description": "The label for category Best practices in sidebar docsSidebar"
},
"sidebar.docsSidebar.category.Source Generator": {
"message": "Source Generator",
"description": "The label for category Source Generator in sidebar docsSidebar"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
# プロジェクト構成

このページでは MagicOnion を使用したプロジェクトの推奨構成について解説します。

.NET アプリケーションでは一般的にソリューションという大きな単位があり、その中にアプリケーションやライブラリーなど .NET のプロジェクトが含まれる形で構成されます。
MagicOnion を使用するアプリケーションはその性質上、最低限サーバーとクライアントのプロジェクトが存在し、何らかの手段でインターフェースを共有するといった構成がとられます。

## 典型的な .NET アプリケーションの構成

ここでは典型的な .NET クライアント (コンソールアプリケーションや WPF、.NET MAUI など) とサーバー、そしてインターフェースを共有する構成例について解説します。

典型的な .NET アプリケーションでのプロジェクト(ソリューション)構成は以下のようになります。

- **MyApp.sln**: ソリューションファイル
- **MyApp.Server**: MagicOnion サーバーアプリケーション (ASP.NET Core gRPC Server)
- このプロジェクトは MagicOnion の API を提供し、クライアントからのリクエストを処理するサーバーアプリケーションです
- **MyApp.Client**: MagicOnion クライアントアプリケーション (Console, WPF, WinForms, .NET MAUI, etc...)
- このプロジェクトは MagicOnion サーバーに接続し、リクエストを送信するクライアントアプリケーションです
- **MyApp.Shared**: インターフェース共有ライブラリー (.NET ライブラリープロジェクト)
- このプロジェクトには MagicOnion 向けのインターフェース定義が含まれます。例えば Hub や Service のインターフェース定義、リクエスト/レスポンスで使用される MessagePack の型などです

:::note
MyApp は任意の名前で、プロジェクト名やソリューション名に置き換えてください。
:::

下記は上記の構成でのファイルの配置例です。

```plaintext
MyApp.sln
|─ src
| ├─ MyApp.Server
| │ ├─ MyApp.Server.csproj
| | ├─ Hubs
| | | ├─ ChatHub.cs
| | └─ Services
| | └─ GreeterService.cs
| ├─ MyApp.Client
| │ ├─ MyApp.Client.csproj
| │ └─ Program.cs
| └─ MyApp.Shared
| ├─ MyApp.Shared.csproj
| ├─ Hubs
| | ├─ IChatHub.cs
| |─ Services
| | └─ IGreeterService.cs
| |─ Requests
| | └─ HelloRequest.cs
| └─ Responses
| └─ HelloResponse.cs
└─ test
└─ MyApp.Server.Test
└─ ...
```

`MyApp.Shared` プロジェクトは .NET クラスライブラリーとして作成し、`MagicOnion.Abstractions` パッケージを参照し、純粋なインターフェースの定義やデータ型、列挙型のみを定義します。
そして `MyApp.Server``MyApp.Client` プロジェクトはそれぞれ `MyApp.Shared` プロジェクトをプロジェクト参照することでインターフェースを共有します。

これは最低限の構成の例であり、実際のプロジェクトでは必要に応じてモデルやドメイン、ViewModel などのプロジェクトや階層を持つことがあります。

## Unity アプリケーションの構成

ここでは Unity クライアントとサーバー、そしてインターフェースを共有する構成例について解説します。

Unity アプリケーションでの構成は Unity プロジェクトとサーバー (.NET) プロジェクトでのインターフェースを共有する方法が典型的な .NET プロジェクトと異なります。
これは Unity プロジェクトからは .NET ライブラリープロジェクトを参照できないといった理由によります。

推奨する構成は以下のようになります。

- **MyApp.Server.sln**: ソリューションファイル
- **MyApp.Server**: MagicOnion サーバーアプリケーション (ASP.NET Core gRPC Server)
- **MyApp.Unity**: Unity クライアントアプリケーション
- **MyApp.Shared**: インターフェース共有ライブラリー (.NET ライブラリープロジェクト兼 Unity ローカルパッケージ)

```plaintext
MyApp.Server.sln
|─ src
| ├─ MyApp.Server
| │ ├─ MyApp.Server.csproj
| │ ├─ Program.cs
| │ ├─ Hubs
| │ │ └─ ChatHub.cs
| │ └─ Services
| │ └─ GreeterHub.cs
| ├─ MyApp.Shared
| │ ├─ MyApp.Shared.csproj
| │ ├─ package.json
| │ ├─ Hubs
| │ │ └─ IChatHub.cs
| │ └─ Services
| │ └─ IGreeterHub.cs
| └─ MyApp.Unity
| ├─ Assembly-CSharp.csproj
| ├─ MyApp.Unity.sln
| └─ Assets
| └─ ...
└─ test
└─ MyApp.Server.Test
└─ ...
```

MyApp.Shared プロジェクトは .NET クラスライブラリーとして作成し、`MagicOnion.Abstractions` パッケージを参照し、純粋なインターフェースの定義やデータ型、列挙型のみを定義します。加えて Unity プロジェクトから Unity Package Manager によって参照できるように `package.json` を含め、`bin`, `obj` といったフォルダーを出力しないように構成します。

`package.json` の内容は下記のような最小構成の JSON ファイルです。

```json
{
"name": "com.cysharp.magiconion.samples.myapp.shared.unity",
"version": "1.0.0",
"displayName": "MyApp.Shared.Unity",
"description": "MyApp.Shared.Unity",
}
```

アセンブリーを分割するために `MyApp.Shared.Unity.asmdef` (Assembly Definition) ファイルを追加することもお勧めします。`.Unity` サフィックスを付けるなど `MyApp.Shared` と完全に同じ名前にならないように注意してください。

次に `MyApp.Shared.csproj` に下記のような設定を追加します。`bin`, `obj` ディレクトリーを作成しないようにする設定と Unity 向けのファイルを IDE 上に表示しないようにする設定です。

```xml
<PropertyGroup>
<!-- https://learn.microsoft.com/en-us/dotnet/core/sdk/artifacts-output -->
<ArtifactsPath>$(MSBuildThisFileDirectory).artifacts</ArtifactsPath>
</PropertyGroup>

<!-- Hide Unity-specific files from Visual Studio and .NET SDK -->
<ItemGroup>
<None Remove="**\package.json" />
<None Remove="**\*.asmdef" />
<None Remove="**\*.meta" />
</ItemGroup>

<!-- Hide build artifacts from Visual Studio and .NET SDK -->
<ItemGroup>
<None Remove=".artifacts\**\**.*" />
<None Remove="obj\**\*.*;bin\**\*.*" />
<Compile Remove=".artifacts\**\**.*" />
<Compile Remove="bin\**\*.*;obj\**\*.*" />
<EmbeddedResource Remove=".artifacts\**\**.*" />
<EmbeddedResource Remove="bin\**\*.*;obj\**\*.*" />
</ItemGroup>
```

この設定により中間ファイルやビルド済みファイルは `.artifacts` 以下に出力されるようになるため、`bin`, `obj` ディレクトリーが作成されている場合は削除してください。

次に Unity プロジェクトの `Packages/manifest.json` に MyApp.Shared への参照を追加します。

```json
{
"dependencies": {
"com.cysharp.magiconion.samples.myapp.shared.unity": "file:../MyApp.Shared/MyApp.Shared.Unity"
}
}
```

MyApp.Server プロジェクトからは MyApp.Shared プロジェクトをプロジェクト参照することでインターフェースを共有します。これは典型的な .NET アプリケーションの場合と同様です。

### SlnMerge によるソリューションの統合

[SlnMerge](https://github.com/Cysharp/SlnMerge) という Unity 向けのエディター拡張を使用することで Unity が生成するソリューションと .NET プロジェクトのソリューションを統合できます。

例えば MyApp.Server.sln には MyApp.Server と MyApp.Shared プロジェクトが含まれますが、Unity で生成されるソリューションには Unity 向けのプロジェクト (Assembly-CSharp, Assembly-CSharp-Editor など) のみが含まれます。SlnMerge を使用することでこれらのソリューションを統合し、Unity からソリューションを開いた場合でもシームレスにサーバープロジェクトを参照できるようになります。

これにより Unity と .NET プロジェクト間での参照検索やデバッガーステップインなどが可能となり開発効率を改善できる場合があります。
Loading

0 comments on commit 27e1528

Please sign in to comment.