WebSurfer's Home

トップ > Blog 1   |   ログイン
APMLフィルター

.NET Framework での Dependency Injection

by WebSurfer 2023年4月13日 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 をインストールしました。

NuGet でインストール

他の 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 版と同様に期待した結果になっています。

実行結果

Tags: ,

.NET Framework

About this blog

2010年5月にこのブログを立ち上げました。主に ASP.NET Web アプリ関係の記事です。

Calendar

<<  2024年4月  >>
31123456
78910111213
14151617181920
21222324252627
2829301234
567891011

View posts in large calendar