🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
.NET

.NETとは、主に.NET Frameworkと呼ばれるアプリケーションまたは開発環境を指します。CLR(共通言語ランタイム)を搭載し、入力された言語をCIL(共通中間言語)に変換・実行することが可能です。そのため、C#やPythonなど複数の言語を用いることができます。

C#

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

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

Q&A

解決済

2回答

947閲覧

依存性を注入したクラスをオブジェクト化する方法

hskwakr

総合スコア9

.NET

.NETとは、主に.NET Frameworkと呼ばれるアプリケーションまたは開発環境を指します。CLR(共通言語ランタイム)を搭載し、入力された言語をCIL(共通中間言語)に変換・実行することが可能です。そのため、C#やPythonなど複数の言語を用いることができます。

C#

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

オブジェクト指向

オブジェクト指向プログラミング(Object-oriented programming;OOP)は「オブジェクト」を使用するプログラミングの概念です。オブジェクト指向プログラムは、カプセル化(情報隠蔽)とポリモーフィズム(多態性)で構成されています。

0グッド

0クリップ

投稿2020/12/30 21:04

編集2020/12/30 22:38

前提

依存性の注入について勉強しています。

練習でコードを書いていて変に思った部分があり、勉強の過程で何かを見逃している気がするので助言をいただきたいと思い質問させていただきました。

具体的に変に思ったのは依存性を注入したクラスをオブジェクト化する時のコードです。

以下のコードは説明のためのサンプルコードです。

サンプルコード

Csharp

1public interface IService 2{ 3 string GetInfomation(); 4} 5 6public class SomethingService : IService 7{ 8 public string GetInfomation() 9 { 10 return "Something"; 11 } 12} 13 14public interface ISpeaker 15{ 16 string Introduce(); 17} 18 19public class User : ISpeaker 20{ 21 private IService _service; 22 23 public User(IService service) 24 { 25 _service = service; 26 } 27 28 public string Introduce() 29 { 30 return "I use a" + _service.GetInfomation(); 31 } 32}

質問

上記のようなコードを作りました。
Userのオブジェクトを作るとき

Csharp

1new User(new SomethingService())

という感じにすると思いますが、例えばIUserの依存性を持つクラス(例えばUserManagerがあったとすれば)のオブジェクトを作るときは

Csharp

1new UserManager(new User(new SomethingService()))

という感じなってオブジェクト化するときに長い列ができて変に感じます。

これが普通なのでしょうか。もしくはこれを回避する方法があるのでしょうか。

また、このオブジェクト化するときのサンプルコードがある記事の探し方が分からず困っていました。
これに関する専門用語などがあれば教えていただきたいです。(日本語|英語 どちらの用語でもかまいません)

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2020/12/30 22:46 編集

> という感じなってオブジェクト化するときに長い列ができて変に感じます。 ならないでしょう。なぜ UserManager があるのに User のコンストラクタを呼び出しているのか意味不明です。注入できてないんじゃないですか?
退会済みユーザー

退会済みユーザー

2020/12/30 23:27 編集

> 依存性の注入について勉強しています。 フレームワーク (DI コンテナ) まで自力で作ろうとしていて、そのための勉強ですか?
hskwakr

2020/12/31 00:40 編集

>> という感じなってオブジェクト化するときに長い列ができて変に感じます。 > >ならないでしょう。なぜ UserManager があるのに User のコンストラクタを呼び出しているのか意味不明です。注入できてないんじゃないですか? 回答していただきありがとうございます。UserManager の中身を考えずに例として出してしまいました。勉強したことを見直してから質問文を編集します。
hskwakr

2020/12/31 00:55 編集

>> 依存性の注入について勉強しています。 > >フレームワーク (DI コンテナ) まで自力で作ろうとしていて、そのための勉強ですか? 回答していただきありがとうございます。DIコンテナというものを知りませんでした。調べてみます。教えていただきありがとうございます。 依存性の注入について勉強している理由は、SOLIDの原則を自分が作っているものに適用したかったからです。
退会済みユーザー

退会済みユーザー

2020/12/31 01:41

> DIコンテナというものを知りませんでした。 Simple Injector など巷に既存の DI コンテナが多々あるそうなのでググって調べてください。DI コンテナの知識はこのスレッドの「依存性の注入」の話をするためには必須です。 Simple Injector なら https://simpleinjector.readthedocs.io/en/latest/quickstart.html を見てもらうと概略が分かるかも。
退会済みユーザー

退会済みユーザー

2020/12/31 01:49

何を作っているのか分かりませんが、もし ASP.NET Core であれば DI コンテナを含めて DI に必要な機能がフレームワークに組み込まれているので、それを使ってください。 .NET Framework ベースの ASP.NET MVC の場合は DI コンテナを組み込む必要があります。Simple Injector の場合のサンプルは https://teratail.com/questions/215282 を見てください。
hskwakr

2021/08/17 10:03 編集

> Simple Injector など巷に既存の DI コンテナが多々あるそうなのでググって調べてください。DI コンテナの知識はこのスレッドの「依存性の注入」の話をするためには必須です。 > Simple Injector なら https://simpleinjector.readthedocs.io/en/latest/quickstart.html を見てもらうと概略が分かるかも。 教えていだたいてありがとうございます。教えていただいたリンクをもとに勉強してみます。勉強してから質問文を見直します。 > 何を作っているのか分かりませんが、もし ASP.NET Core であれば DI コンテナを含めて DI に必要な機能がフレームワークに組み込まれているので、それを使ってください。 背景の説明が足りず、すみません。 .NET Core 3.1 のコンソールアプリケーションを作っています。
退会済みユーザー

退会済みユーザー

2020/12/31 02:45

Core ベースのコンソールアプリなら ASP.NET Core が使っている Microsoft.Extensions.DependencyInjection が使えるかもしれません。
guest

回答2

0

サンプルコードのIServiceCollectionの作り方がわからなかったので、Use dependency injection in .NET | Microsoft Docsのサンプルコードを参考にして実現できました。

Csharp

1using System; 2using System.Threading.Tasks; 3using Microsoft.Extensions.DependencyInjection; 4using Microsoft.Extensions.Hosting; 5 6namespace ConsoleAppDependencyInjection 7{ 8 public class Program 9 { 10 public static Task Main(string[] args) 11 { 12 IHost host = CreateHostBuilder(args).Build(); 13 14 CreateScope(host.Services); 15 16 return host.RunAsync(); 17 } 18 19 private static IHostBuilder CreateHostBuilder(string[] args) 20 { 21 return Host.CreateDefaultBuilder(args) 22 .ConfigureServices((_, services) => 23 services.AddSingleton<IOrderRepository, SqlOrderRepository>() 24 .AddSingleton<ILogger, Logger>() 25 .AddSingleton<CancelOrderHandler>()); 26 } 27 28 private static void CreateScope(IServiceProvider services) 29 { 30 using IServiceScope serviceScope = services.CreateScope(); 31 IServiceProvider provider = serviceScope.ServiceProvider; 32 33 var cancelHandler = provider.GetRequiredService<CancelOrderHandler>(); 34 cancelHandler.Handle(); 35 } 36 } 37}

投稿2021/01/04 21:09

編集2021/01/04 21:14
hskwakr

総合スコア9

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hskwakr

2021/01/04 21:39 編集

var serviceCollection = new ServiceCollection(); で取れました。お騒がせしました。
guest

0

ベストアンサー

質問のコメント欄に、Core ベースのコンソールアプリなら ASP.NET Core が使っている Microsoft.Extensions.DependencyInjection が使えるかもしれませんと書きましたが、使えました。

それを使って以下の Simple Injector の記事と同様なものを実装できます。以下にそのサンプルをアップしておきます。

Quick Start
https://simpleinjector.readthedocs.io/en/latest/quickstart.html

上の Simple Injector の記事のサンプルと全く同じではありませんが、質問に書いてあった、

例えばIUserの依存性を持つクラス(例えばUserManagerがあったとすれば)のオブジェクトを作るときは

の疑問に答えているのではないかと思います。

Microsoft.Extensions.DependencyInjection の詳しい話は以下の記事が参考になると思います。

Microsoft.Extensions.DependencyInjection Deep Dive
https://gist.github.com/yfakariya/11e40a5ebf537ee545cfdd3b6e8c5fbe

using System; using Microsoft.Extensions.DependencyInjection; // Microsoft.Extensions.DependencyInjection は NuGet でインストール namespace ConsoleAppDependencyInjection { class Program { static void Main(string[] args) { IServiceCollection services = new ServiceCollection(); services.AddSingleton<IOrderRepository, SqlOrderRepository>(); services.AddSingleton<ILogger, Logger>(); services.AddSingleton<CancelOrderHandler>(); var provider = services.BuildServiceProvider(); var handler = provider.GetRequiredService<CancelOrderHandler>(); handler.Handle(); } } public class CancelOrderHandler { private readonly IOrderRepository repository; private readonly ILogger logger; // Use constructor injection for the dependencies public CancelOrderHandler(IOrderRepository repository, ILogger logger) { this.repository = repository; this.logger = logger; } public void Handle() { this.logger.Log("Cancelling order"); this.repository.GetById(); this.repository.Save(); } } public interface IOrderRepository { public void GetById(); public void Save(); } public class SqlOrderRepository : IOrderRepository { private readonly ILogger logger; public SqlOrderRepository(ILogger logger) { this.logger = logger; } public void GetById() { this.logger.Log("Getting Order"); // Retrieve from db. } public void Save() { this.logger.Log("Saving order"); // Save to db. } } public interface ILogger { void Log(string log); } public class Logger : ILogger { public void Log(string log) { Console.WriteLine(log); } } }

実行結果は以下のようになります。

イメージ説明

投稿2020/12/31 05:27

編集2020/12/31 05:36
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hskwakr

2020/12/31 06:02

教えていただきありがとうございました。DIコンテナを含めてもう一度勉強しなおします。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問