-
간단한 디펜던시 인젝션(DI) 구현프로그래밍/기록, 개념, 용어 2022. 11. 14. 14:21반응형
Singleton, Transient, Scoped 같은 라이프타임은 제외하고, 어떻게 생성자가 요구하는 인자들을 순서대로 전달하는지에 대해 초점을 맞췄습니다.
아래에 HelloService가 있습니다.
HelloService 클래스는 생성자에서 string과 List<string>을 파라미터로 가지고 있습니다.
우리는 이 HelloService를 생성할 때, 외부에서 지정한 인자들을 주입하는 것이 목적입니다.
class HelloService { private string _header; private List<string> _contents; public HelloService(string header, List<string> contents) { _header = header; _contents = contents; } public void Hello() { Console.WriteLine(_header); foreach (string content in _contents) { Console.WriteLine(content); } } }
먼저 HelloService의 생성자와, 생성자 파라미터 정보를 가져오는 방법은 아래와 같습니다.
// 생성자 정보를 가져옴. ConstruectorInfo? ctorInfo = typeof(HelloService).GetConstructors().Single(); // 생성자 파라미터 정보를 가져옴. ParameterInfo[]? paramInfos = ctorInfo.GetParameters(); // 생성자 파라미터 정보에서 파라미터 타입들을 가져옴. Type[] paramTypes = paramInfos.Select(pi => pi.ParameterType).ToArray();
그리고 특정 타입의 인스턴스를 만드는 방법은 아래와 같습니다.
Type helloServiceType = typeof(HelloService); object[] ctorArgs = new object[]{}; object helloServiceInstance = Activator.CreateInstance(helloServiceType, ctorArgs);
그리고 디펜던시 인젝션에 사용될 ServiceCollection은 아래와 같습니다.
이 클래스의 기능은 타입과, 타입의 인스턴스 저장하고, 가져오는 것 밖에 없습니다.
public class ServiceCollection { Dictionary<Type, object?> _items = new(); public void AddSingleton<T>(T item) { _items.Add(typeof(T), item); } public object GetSingleton(Type type) { return _items[type]!; } }
위 요소들로 디펜던시 인젝션을 활용한 인스턴스 생성하는 코드입니다.
using System.Reflection; using System.Collections.Generic; using System.Linq; using System; class HelloService { private string _header; private List<string> _contents; public HelloService(string header, List<string> contents) { _header = header; _contents = contents; } public void Hello() { Console.WriteLine(_header); foreach (string content in _contents) { Console.WriteLine(content); } } } public class ServiceCollection { Dictionary<Type, object?> _items = new(); public void AddSingleton<T>(T item) { _items.Add(typeof(T), item); } public object GetSingleton(Type type) { return _items[type]!; } } static class Program { public static void Main(string[] _) { ServiceCollection collection = new (); collection.AddSingleton("header"); collection.AddSingleton(new List<string>() { "hello", "world", "!" }); // 생성자 정보를 가져옴. ConstructorInfo ctorInfo = typeof(HelloService).GetConstructors().Single(); // 생성자 파라미터 정보를 가져옴. ParameterInfo[]? paramInfos = ctorInfo.GetParameters(); // 생성자 파라미터의 타입들을 가져옴. IEnumerable<Type> paramTypes = ctorInfo .GetParameters() .Select(paramInfo => paramInfo.ParameterType); object[] ctorArgs = paramTypes.Select(collection.GetSingleton).ToArray(); HelloService helloService = (HelloService)Activator.CreateInstance(typeof(HelloService), ctorArgs)!; helloService.Hello(); } }
결과
반응형'프로그래밍 > 기록, 개념, 용어' 카테고리의 다른 글
EF Core로 날짜(DateTime) 필드 타입은 DateTimeOffset으로 (0) 2022.11.29 C#, xUnit으로 테스트 (0) 2022.11.27 ASP.NET CORE에서의 클레임 키 임의 변경 (0) 2022.11.04 C# Channel (0) 2022.10.28 C# - ArrayPool, MemoryPool (0) 2022.10.13