15 Temmuz 2018

C# ile basit bir Inversion Of Control (IoC) Örneği

Burada verilen örnek ile basit bir IoC çalışma mantığı gösterme hedeflenmiştir.
Kararlı bir IoC kütüphanesi için Castle Windsor inceleyiniz.


using System;
using System.Collections.Generic;
using System.Linq;

namespace DIP
{
    class Program
    {
        static void Main(string[] args)
        {
            var ioc = new SimpleIoC();
            ioc.Register<IPrinter, ConsolePrinter>();
            ioc.Register<Test, Test>();

            var test = ioc.Resolve<Test>();
            test.Hello("Ali");
        }
    }

    interface IPrinter
    {
        void Print(string text);
    }
    class ConsolePrinter : IPrinter
    {
        public void Print(string text)
        {
            Console.WriteLine(text);
        }
    }
    class Test
    {
        private readonly IPrinter printer;
        public Test(IPrinter printer)
        {
            this.printer = printer;
        }
        public void Hello(string name) => printer.Print($"Hello {name}");
    }
    public class SimpleIoC
    {
        private readonly Dictionary<Type, Type> _map = new Dictionary<Type, Type>();
        public void Register<TFrom, TTo>() => _map.Add(typeof(TFrom), typeof(TTo));

        public T Resolve<T>() => (T)Resolve(typeof(T));

        private object Resolve(Type type)
        {
            Type resolvedType = null;
            try
            {
                resolvedType = _map[type];
            }
            catch (Exception)
            {
                throw new ArgumentException($"Couldn't resolve the type {type}");
            }

            var ctor = resolvedType.GetConstructors().First();
            var ctorParameters = ctor.GetParameters();

            if (ctorParameters.Length == 0)
                return Activator.CreateInstance(resolvedType);

            var parameters = new List<object>();
            foreach (var parameterToResolve in ctorParameters)
            {
                parameters.Add(Resolve(parameterToResolve.ParameterType));
            }
            return ctor.Invoke(parameters.ToArray());
        }
    }
}