質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
86.12%
DI (Dependence Injection)

DI (Dependence Injection)は、「依存性の注入」という概念を指します。オブジェクト間で依存性のあるコードを外部の設定ファイルから注入するソフトウェアパターン設計思想です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

解決済

DIの設定を記述する場所が分からない

nerese
nerese

総合スコア1

DI (Dependence Injection)

DI (Dependence Injection)は、「依存性の注入」という概念を指します。オブジェクト間で依存性のあるコードを外部の設定ファイルから注入するソフトウェアパターン設計思想です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。

1回答

0グッド

1クリップ

255閲覧

投稿2022/10/23 15:12

前提

C#でASP.Netを用いてWebアプリケーションを構築しようとしています。
レイヤードアーキテクチャに従い、プロジェクトを以下の4つに分けました。

  • Presentation(ASP.NETで作成したものでViewを保持)
    • 参照:Application
  • Application(Controllerを保持)
    • 参照:Domain
  • Domain(Entity/Service/IRepositoryを保持)
    • 参照:なし
  • Infrastructure(Repositoryを保持)
    • 参照:Domain

ServiceクラスにはIRepositoryを受け取るコンストラクタを用意し、
Infrastructureの実装クラスをDIにて挿入すればよいというところまでは理解したのですが、
このDIに関する設定(コンテキスト)はどのレイヤーで生成すれ良いのかが分かりません。

該当のソースコード

C#

1public interface IHogehogeRepository : IDisposable 2{ 3 : 4}

C#

1public class HogehogeService : IHogehogeService 2{ 3 private readonly IHogehogeRepository _hogehogeRepository; 4 public HogehogeService (IHogehogeRepository hogehogeRepository) 5 { 6 _hogehogeRepository = hogehogeRepository 7 } 8 : 9}

C#

1public class HogehogeSQLServerRepository : IHogehogeRepository 2{ 3 : 4}

試したこと

autofacを用いて以下の2クラスを用意し、
としてこれをGlobal.asaxのApplication_Start()から呼び出すことで
DI自体が機能するのことまでは確認できました。

ただこの場合、IHogehogeRepositoryインターフェイスとHogehogeSQLServerRepositoryクラスを参照するために
PresentationプロジェクトにDomainとInfrastructureの参照を追加する必要がありました。

DIの設定のためとはいえこれら2つの参照を追加する必要があるのかという点が疑問です。

上記のような場合、DIに関する設定はPresentationプロジェクトに入れるのが正しいのか
それともApplicationプロジェクトにInfrastructureへの参照を追加して入れるのが正しいのかどちらでしょうか?
あるいは他の手段を用いるべきなのでしょうか?
ご教示いただけますと幸いです。

C#

1public class Dependency : IDependencyResolver 2{ 3 private readonly IContainer container; 4 public Dependency(IContainer container) 5 { 6 this.container = container; 7 } 8 9 public object GetService(Type serviceType) 10 { 11 return container.IsRegistered(serviceType) ? container.Resolve(serviceType) : null; 12 } 13 14 public IEnumerable<object> GetServices(Type serviceType) 15 { 16 Type enumerableServiceType = typeof(IEnumerable<>).MakeGenericType(serviceType); 17 18 object instance = container.Resolve(enumerableServiceType); 19 20 return ((IEnumerable)instance).Cast<object>(); 21 } 22}

C#

1internal class DependencyConfigure 2{ 3 public static void Initialize() 4 { 5 var builder = new ContainerBuilder(); 6 DependencyResolver.SetResolver(new Dependency(RegisterServices(builder))); 7 } 8 9 private static IContainer RegisterServices(ContainerBuilder builder) 10 { 11 builder.RegisterAssemblyTypes(typeof(Global).Assembly).PropertiesAutowired(); 12 13 builder.RegisterType<HogehogeSQLServerRepository>().As<IHogehogeRepository>(); 14 15 return builder.Build(); 16 } 17}

補足情報(FW/ツールのバージョンなど)

.Net Framework 4.8
VisualStudio Community 2022 Version 17.3.1
Autofac 6.4.0

以下のような質問にはグッドを送りましょう

  • 質問内容が明確
  • 自分も答えを知りたい
  • 質問者以外のユーザにも役立つ

グッドが多くついた質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

気になる質問をクリップする

クリップした質問は、後からいつでもマイページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

下記のような質問は推奨されていません。

  • 間違っている
  • 質問になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

適切な質問に修正を依頼しましょう。

SurferOnWww

2022/10/23 22:50

> レイヤードアーキテクチャに従い、プロジェクトを以下の4つに分けました。 何故プロジェクトを分ける必要があるのですか? Visual Studio のテンプレートを利用して作るプロジェクトそのままで、単一プロジェクト内でフォルダを分ければ悩みは解消しそうな気がしますけど。
nerese

2022/10/24 08:24

ご連絡いただきありがとうございます。 上記質問の際には説明が足りておらず申し訳ございません。 Webアプリケーション用のdllとは別に、バッチ実行用のプロジェクトをコンソールアプリケーションとして作成し、コンパイル後のexeからもServiceのロジックを呼び出したいと考えています。(exeからもアプリケーションレイヤーにコントローラーを用意して呼び出す方が正しいのかもしれません) そこで、Domain層のみでdll化できるよう、MVCプロジェクトを作成した後にレイヤー毎にプロジェクトを分けた次第です。
SurferOnWww

2022/10/24 13:47

説明いただいたのにすみませんが、何をしたいのかよくわかりません。質問者さんは ASP.NET MVC5 の開発経験・知識は十分にお持ちですか? Controller と View を別プロジェクトに分けるというようなことが書いてありますが、そこからして自分としては不可解なのですが・・・
nerese

2022/10/24 14:43

ご連絡ありがとうございます。 SEとして仕事をしておりますが、これまではJavaの経験の方が長く、ASP.NET MVCの経験が十分かといえば至らぬ点も多々あるかと思っております。 顧客環境ではWindowsServer上にIISを立てているものの、昨今の事情もありJavaは使わない方針となったり、使用しているDBがODBC接続しかできないため、EntityFrameworkも使用できなかったり、.NET Frameworkも4.8であり、.Net Core/.Netを選択することもできないなど、様々な事情が制限として存在するため、ASP.NET MVCでオンライン画面を用意する方針をとっています。 こちらで質問させていただくまでに調べたことで、Microsoftが提唱しているUnitOfWorkと私が行おうとしているDDDベースのRepositoryパターンとでは方向性が異なる(Core側ではMicrosoftもDDDについて言及されているような記事を読みましたが)ことなど、Microsoftが想定していた構成には沿っていない、逆行しようとしているという点については認識を持っています。 一方で、オンライン画面から行える一部の処理は、オンバッチ方式とし、画面からも実行できるものの、主たるトリガーはバッチ起動とするものがある状況です。 Serviceに実装するbussinesslogicと同じコードを別のコンソールアプリのプロジェクトにもコピーしてexe化するという方法が一番早く実現できるとは思っていますが、今後の改修が発生する可能性を考慮すると、MVC側のロジックのみをdll化し、exe側からも呼び出せるようにしたいと思っています。 そもそもバッチフレームワークを用いるという手もあるのかもしれませんが、こちらは更に経験がなく、またテスト工数が肥大化しないかという懸念もある状況です。。。 Javaの場合はSpringBootを用いることで別のプロジェクトでコンパイルした結果のDIも用意であったことから、C#でもDIライブラリを用いることで同様なことが実現できないかと期待しております。
SurferOnWww

2022/10/25 22:45

質問者さん、その後無言ですが、回答したのでそれに対するフィードバックを返してください。役に立った/立たなかったぐらいはすぐに返せるのでは? 役に立たなかったならどこがダメかを書くとより期待に近い回答が出てくるかも。とにかく無言は NG です。
nerese

2022/10/25 23:21 編集

確認が遅くなり、また返答が遅くなり申し訳ございません。 ここまでお付き合い頂きましたこと、また、「DI コンテナの作成・登録のために参照の追加が必要なら、やらざるを得えない」との方針をご提示頂きまして誠にありがとうございます。 BAに選ばせていただきました。 頂いた内容を踏まえ業務案件を進めるため、邁進してまいります。 私の理解が及んでいないことも多く、ご迷惑をおかけしたところも多々あったかと思いますが、またの機会にはご助力を賜れますと幸いです。

回答1

0

ベストアンサー

質問者さんのやりたいことの詳細が十分理解できていませんが、要点は以下の通りと理解してレスします。

(1) リポジトリパターンを実装する。以下の図を見てください。

イメージ説明

出典: ASP.NET MVC 実践プログラミング(秀和システム)

(2) ASP.NET MVC5 アプリに Autofac.Mvc をインストールして DI 機能を実装する。

(3) 上の図の「本番用クラス」をバッチ実行用のコンソールアプリケーションでも利用できるように、別プロジェクトに切り出して dll として作成する。

上の理解で正しければ、まず Visual Studio 2022 のテンプレートを利用してプロジェクトを作成し、そのプロジェクトに上の図のように Controller, View, Model 他必要なすべてを実装し、「本番用クラス」だけを別プロジェクトに切り出すというアプローチを取ってはいかがですか?

DIの設定を記述する場所が分からない

DI を設定する場所は ASP.NET MVC アプリでなければなりません。上の図で言うと「コントローラクラス」のあるプロジェクトです。

ASP.NET MVC アプリの場合、クライアントからの要求を受けて ASP.NET が Controller のインスタンスを作り、それで要求を処理し、View を使って応答を作成してクライアントに返すという操作を行います。

DI 機能を使う場合、その Controller と「本番用クラス」を含んだ DI コンテナを初期化し、ASP.NET に登録することになります。それにより、ASP.NET が Controller のインスタンスを作る際、DI 機能が働いて、自動的に「本番用クラス」のインスタンスへの参照がコンストラクタ経由で inject されます。

具体な DI 機能の設定例は以下の記事が参考になると思います。(質問のコードはどこから持ってきたのでしょう?)

ASP.NET MVC 5でAutofacを使う
https://www.nuits.jp/entry/2018/02/09/133526

DIの設定のためとはいえこれら2つの参照を追加する必要があるのかという点が疑問です。

上に述べた ASP.NET MVC アプリの Global.asax の Application_Start メソッドでの DI コンテナの作成・登録のために参照の追加が必要なら、やらざるを得ません。

投稿2022/10/25 02:23

SurferOnWww

総合スコア17328

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

下記のような回答は推奨されていません。

  • 間違っている回答
  • 質問の回答になっていない投稿
  • スパムや攻撃的な表現を用いた投稿

このような回答には修正を依頼しましょう。

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

同じタグがついた質問を見る

DI (Dependence Injection)

DI (Dependence Injection)は、「依存性の注入」という概念を指します。オブジェクト間で依存性のあるコードを外部の設定ファイルから注入するソフトウェアパターン設計思想です。

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

ASP.NET

ASP.NETは動的なWebサイトやWebアプリケーション、そしてWebサービスを構築出来るようにする為、Microsoftによって開発されたウェブアプリケーション開発フレームワークです。