by WebSurfer
13. April 2023 15:12
ASP.NET Core で Dependency Injection (DI) に使われている Microsoft.Extensions.DependencyInjection 名前空間にあるクラス類は .NET Framework でもバージョン 4.6.1 以降であれば利用できるそうですので、.NET Framework 4.8 のコンソールアプリで試してみました。
先の記事「.NET Core での Dependency Injection」でターゲットフレームワーク .NET 5.0 のコンソールアプリに DI 機能を実装してみましたが、その .NET Framework 4.8 版です。
まず、Visual Studio 2022 のテンプレートを使ってターゲットフレームワーク .NET Framework 4.8 でコンソースアプリを作成し、NuGet から Microsoft.Extensions.DependencyInjection をインストールします。この記事を書いた時点での最新版 7.0.0 をインストールしました。

他の Micosoft.Bcl.AsyncInterfaces などのパッケージは Microsoft.Extensions.DependencyInjection をインストールした時に同時に自動的にインストールされたものです。
検証に使ったコードは以下の通りです。先の記事「.NET Core での Dependency Injection」のものと同じです。
using Microsoft.Extensions.DependencyInjection;
using System;
namespace ConsoleAppDependencyInjection
{
internal class Program
{
static void Main(string[] args)
{
IServiceCollection services = new ServiceCollection();
services.AddTransient<IOrderRepository, SqlOrderRepository>();
services.AddSingleton<ILogger, Logger>();
services.AddScoped<IEventPublisher, EventPublisher>();
services.AddTransient<CancelOrderHandler>();
var provider = services.BuildServiceProvider();
var handler = provider.GetRequiredService<CancelOrderHandler>();
var orderId = Guid.NewGuid();
var command = new Order { OrderId = orderId };
handler.Handle(command);
}
}
public class CancelOrderHandler
{
private readonly IOrderRepository repository;
private readonly ILogger logger;
private readonly IEventPublisher publisher;
// Use constructor injection for the dependencies
public CancelOrderHandler(IOrderRepository repository,
ILogger logger,
IEventPublisher publisher)
{
this.repository = repository;
this.logger = logger;
this.publisher = publisher;
}
public void Handle(Order command)
{
this.logger.Log($"Cancelling order {command.OrderId}");
var order = this.repository.GetById(command.OrderId);
order.OrderStatus = "Cancelled";
this.repository.Save(order);
this.publisher.Publish(order);
}
}
public interface IOrderRepository
{
Order GetById(Guid orderId);
void Save(Order order);
}
public class SqlOrderRepository : IOrderRepository
{
private readonly ILogger logger;
// Use constructor injection for the dependencies
public SqlOrderRepository(ILogger logger)
{
this.logger = logger;
}
public Order GetById(Guid orderId)
{
this.logger.Log($"Getting Order {orderId}");
// Retrieve from db.・・・のつもり
var order = new Order
{
OrderId = orderId,
ProductName = "911-GT3",
OrderStatus = "Ordered"
};
return order;
}
public void Save(Order order)
{
this.logger.Log($"Saving order {order.OrderId}");
// Save to db.
}
}
public interface ILogger
{
void Log(string log);
}
public class Logger : ILogger
{
public void Log(string log)
{
Console.WriteLine(log);
}
}
public interface IEventPublisher
{
void Publish(Order order);
}
public class EventPublisher : IEventPublisher
{
public void Publish(Order order)
{
Console.WriteLine($"Publish order {order.OrderId}, " +
$"{order.ProductName}, {order.OrderStatus}");
}
}
public class Order
{
public Guid OrderId { get; set; }
public string ProductName { get; set; }
public string OrderStatus { get; set; }
}
}
実行結果は以下の画像のようになります。先の記事の .NET 5.0 版と同様に期待した結果になっています。
