2021年12月10日 星期五

multiple implementations of a same interface

一個Interface實作多個類別

在沒有DI的時候,都會用簡單工廠來實作,如下

using Microsoft.AspNetCore.Mvc;
using System;

using WebApplication1.Service;

namespace WebApplication1.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class ExampleController : ControllerBase
    {
        public IExample GetInstance(string className)
        {
            IExample result;
            switch (className)
            {
                case "ExampleA":
                    result = new ExampleA();
                    break;
                case "ExampleB":
                    result = new ExampleB();
                    break;
                case "ExampleC":
                    result = new ExampleC();
                    break;
                default:
                    throw new NotImplementedException();
            }
            return result;
        }


        [HttpGet]
        public string Get()
        {
            return GetInstance("ExampleA").GetName();
        }
    }
}

這種方式也沒有什麼不好,只是實作類別一多會switch很長
但有了DI之後再也不在使用Factory的方式取得實作,變成以下方式

using Microsoft.AspNetCore.Mvc;
using System;
using System.Collections.Generic;
using System.Linq;

namespace WebApplication1.Controllers
{
    [ApiController]
    [Route("[controller]")]
    public class ExampleController : ControllerBase
    {
        private readonly IExample _example;
        public ExampleController(IEnumerable<IExample> examples)
        {
            _example = examples.Single(x => x.Type == ExampleType.ExampleA);
        }

        [HttpGet]
        public string Get()
        {
            return _example.GetName();
        }

        public enum ExampleType
        {
            ExampleA,
            ExampleB,
            ExampleC
        }

        public interface IExample
        {
            public ExampleType Type { get; }
            public string GetName();
        }

        public class ExampleA : IExample
        {
            public ExampleType Type => ExampleType.ExampleA;

            public string GetName()
            {
                return "ExampleA";
            }
        }

        public class ExampleB : IExample
        {
            public ExampleType Type => ExampleType.ExampleB;

            public string GetName()
            {
                return "ExampleB";
            }
        }

        public class ExampleC : IExample
        {
            public ExampleType Type => ExampleType.ExampleC;

            public string GetName()
            {
                return "ExampleC";
            }
        }
    }
}

Startup.cs註冊
public void ConfigureServices(IServiceCollection services)
{
    services.AddControllers();
    services.AddScoped<IExample, ExampleA>();
    services.AddScoped<IExample, ExampleB>();
    services.AddScoped<IExample, ExampleB>();
}
之後有新增實作的話,只需要在註冊進去就可以直接使用
替換類別也非常的快速,而且關注點很清楚!!

沒有留言:

張貼留言