背景

为了帮助我更好地理解IOC及其使用方法,我想创建所有三种IOC技术的示例:构造器注入(inject),Setter注入(inject)和接口(interface)注入(inject),而无需使用第三方框架。我想我有一个构造函数注入(inject)的基本示例,但是在setter和interface注入(inject)方面苦苦挣扎。

我的问题

从头开始,您将如何处理书写界面和二传手注入(inject)?

这是我的想法,请告诉我我的工作是否正确。

接口(interface)注入(inject):

  • 循环遍历使用构造函数注入(inject)实例化的已解析对象,检查以查看在interfaceDependencyMap
  • 中实现了哪些接口(interface)
  • 定义某种interfaceDependencyMap,以将接口(interface)与实现相关联。
  • 使用interfaceDependencyMap
  • 解决实现
  • 为使用构造函数注入(inject)初始化的对象分配适当的属性

  • 二传手注入(inject):
  • 循环遍历使用构造函数注入(inject)
  • 实例化的已解析对象
  • 定义某种setterInjectionMap
  • 使用构造函数映射
  • 从MethodInfo解析期望的参数
  • 调用setter方法,传入已解析的参数对象

  • 到目前为止,这是我要进行构造函数注入(inject)的内容
    public class Program
    {
        static void Main(string[] args)
        {
            //
            //instead of doing this:
            //
            //ICreditCard creditCard = new Visa();
            //var customer = new Customer(creditCard);
            //customer.Charge();
    
    
            var resolver = new Resolver();
    
            //map the types in the container
            resolver.Register<Customer, Customer>();
            resolver.Register<ICreditCard, Visa>();
    
            //because the customer constructor has an ICreditCard parameter
            //our container will automatically instantiate it recursively
            var customer = resolver.Resolve<Customer>();
    
            customer.Charge();
    
        }
    }
    
    public interface ICreditCard
    {
        string Charge();
    }
    
    public class Visa : ICreditCard
    {
        public string Charge()
        {
            return "Charging Visa";
        }
    }
    
    public class MasterCard : ICreditCard
    {
        public string Charge()
        {
            return "Charging MasterCard";
        }
    }
    
    public class Customer
    {
        private readonly ICreditCard _creditCard;
    
        public Customer(ICreditCard creditCard)
        {
            this._creditCard = creditCard;
        }
    
        public void Charge()
        {
            _creditCard.Charge();
        }
    }
    
    
    public class Resolver
    {
        private Dictionary<Type, Type> dependencyMap = new Dictionary<Type, Type>();
    
        public T Resolve<T>()
        {
            return (T) Resolve(typeof (T));
        }
    
        private object Resolve(Type typeToResolve)
        {
            Type resolvedType = null;
    
            try
            {
                resolvedType = dependencyMap[typeToResolve];
            }
            catch
            {
                throw new Exception(string.Format("could not resolve type {0}", typeToResolve.FullName));
            }
    
            var firstConstructor = resolvedType.GetConstructors().First();
            var constructorParameters = firstConstructor.GetParameters();
            if (constructorParameters.Count() == 0)
                return Activator.CreateInstance(resolvedType);
    
            IList<object> parameters = constructorParameters.Select(parameterToResolve => Resolve(parameterToResolve.ParameterType)).ToList();
    
            return firstConstructor.Invoke(parameters.ToArray());
        }
    
        public void Register<TFrom, TTo>()
        {
            dependencyMap.Add(typeof (TFrom), typeof (TTo));
        }
    }
    

    最佳答案

    您在找这种东西吗?

    class Container
    {
        class Registration
        {
            public Type RegistrationType;
            public Func<Container, object> Resolver;
        }
    
        List<Registration> registrations = new List<Registration>();
    
        public object Resolve(Type type)
        {
            return registrations
                .First(r => type.IsAssignableFrom(r.RegistrationType))
                .Resolver(this);
        }
    
        public T Resolve<T>()
        {
            return (T)Resolve(typeof(T));
        }
    
        public void Register<T>(Func<Container, T> registration) where T : class
        {
            registrations.Add(new Registration()
            {
                RegistrationType = typeof(T),
                Resolver = registration
            });
        }
    }
    

    用法:
    interface IDependency
    {
        string GetName();
    }
    
    class ConcreteDependency : IDependency
    {
        public string GetName()
        {
            return "Concrete Dependency";
        }
    }
    
    class ConstructorExample
    {
        readonly IDependency dependency;
    
        public ConstructorExample(IDependency dependency)
        {
            this.dependency = dependency;
        }
    
        public string GetString()
        {
            return "Consumer of " + dependency.GetName();
        }
    }
    
    class SetterExample
    {
        public IDependency Dependency { get; set; }
    
        public string GetString()
        {
            return "Consumer of " + Dependency.GetName();
        }
    }
    
    [TestMethod]
    public void MyTestMethod()
    {
        var container = new Container();
        container.Register<IDependency>(c => new ConcreteDependency());
        container.Register(c => new ConstructorExample(c.Resolve<IDependency>()));
        container.Register(c => new SetterExample() { Dependency = c.Resolve<IDependency>() });
    
        var constructor = container.Resolve<ConstructorExample>();
        Assert.AreEqual("Consumer of Concrete Dependency", constructor.GetString());
    
        var setter = container.Resolve<SetterExample>();
        Assert.AreEqual("Consumer of Concrete Dependency", setter.GetString());
    }
    

    如果您想更高级,我建议您获取以下任意一种的来源:SimpleInjectorAutofacNinjectStructureMap

    关于c# - 自定义IOC容器-需要2/3类型的帮助,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8408675/

    10-16 12:42