C# 自定义IOC容器-需要关于2/3类型的帮助 背景

C# 自定义IOC容器-需要关于2/3类型的帮助 背景,c#,inversion-of-control,ioc-container,C#,Inversion Of Control,Ioc Container,为了帮助提高我对IOC的理解以及如何使用它,我想创建一个所有三种IOC技术的示例:构造函数注入、Setter注入和接口注入,而不必使用第三方框架。我想我有一个构造函数注入的基本示例,但是在setter和接口注入方面遇到了困难 我的问题 您将如何从头开始处理编写接口和setter注入 这是我的想法,让我知道我是否在正确的轨道上 界面注入: 循环使用构造函数注入实例化的已解析对象,查看interfaceDependencyMap中实现了哪些接口 定义某种interfaceDependencyMap以

为了帮助提高我对IOC的理解以及如何使用它,我想创建一个所有三种IOC技术的示例:构造函数注入、Setter注入和接口注入,而不必使用第三方框架。我想我有一个构造函数注入的基本示例,但是在setter和接口注入方面遇到了困难

我的问题 您将如何从头开始处理编写接口和setter注入

这是我的想法,让我知道我是否在正确的轨道上

界面注入:

  • 循环使用构造函数注入实例化的已解析对象,查看interfaceDependencyMap中实现了哪些接口
  • 定义某种interfaceDependencyMap以将接口与实现关联
  • 使用interfaceDependencyMap解决实现问题
  • 为使用构造函数注入初始化的对象分配适当的属性
  • 设定器注入:

  • 循环通过使用构造函数注入实例化的已解析对象
  • 定义某种类型的setterInjectionMap
  • 使用构造函数映射从MethodInfo解析所需参数
  • 调用传递已解析参数对象的setter方法
  • 这是我到目前为止关于构造函数注入的内容
    公共类程序
    {
    静态void Main(字符串[]参数)
    {
    //
    //而不是这样做:
    //
    //ICreditCard信用卡=新Visa();
    //var客户=新客户(信用卡);
    //客户费用();
    var resolver=new resolver();
    //映射容器中的类型
    resolver.Register();
    resolver.Register();
    //因为客户构造函数有一个ICreditCard参数
    //我们的容器将自动递归地实例化它
    var customer=resolver.Resolve();
    客户费用();
    }
    }
    公共接口卡
    {
    字符串电荷();
    }
    公共类签证:ICreditCard
    {
    公共字符串费用()
    {
    返回“收费签证”;
    }
    }
    公共级万事达卡:ICreditCard
    {
    公共字符串费用()
    {
    返回“充电万事达卡”;
    }
    }
    公共类客户
    {
    私人只读ICreditCard(信用卡);;
    公众客户(ICreditCard信用卡)
    {
    这个。_creditCard=信用卡;
    }
    公共收费()
    {
    _信用卡收费;
    }
    }
    公共类解析器
    {
    private Dictionary dependencyMap=新字典();
    公共事务解决方案
    {
    返回(T)解析(类型(T));
    }
    私有对象解析(类型typeToResolve)
    {
    类型resolvedType=null;
    尝试
    {
    resolvedType=dependencyMap[TypeToResolved];
    }
    抓住
    {
    抛出新异常(string.Format(“无法解析类型{0}”,typeToResolve.FullName));
    }
    var firstConstructor=resolvedType.GetConstructors().First();
    var constructorParameters=firstConstructor.GetParameters();
    if(constructorParameters.Count()==0)
    返回Activator.CreateInstance(resolvedType);
    IList parameters=constructorParameters.Select(parameterToResolve=>Resolve(parameterToResolve.ParameterType)).ToList();
    返回firstConstructor.Invoke(parameters.ToArray());
    }
    公开作废登记册()
    {
    dependencMap.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
            });
        }
    }
    
    类容器
    {
    班级注册
    {
    公共类型注册类型;
    公共函数解析器;
    }
    列表注册=新列表();
    公共对象解析(类型)
    {
    返回注册
    .First(r=>type.IsAssignableFrom(r.RegistrationType))
    .解析器(本);
    }
    公共事务解决方案
    {
    返回(T)解析(类型(T));
    }
    公共无效注册(Func注册),其中T:class
    {
    注册。添加(新注册()
    {
    注册类型=类型(T),
    解析器=注册
    });
    }
    }
    
    用法:

    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());
    }
    
    接口独立性
    {
    字符串GetName();
    }
    类依赖:IDependency
    {
    公共字符串GetName()
    {
    返回“具体依赖”;
    }
    }
    类构造函数示例
    {
    只读独立依赖关系;
    公共构造示例(IDependency依赖)
    {
    依赖性=依赖性;
    }
    公共字符串GetString()
    {
    返回“Consumer of”+dependency.GetName();
    }
    }
    类集合示例
    {
    公共IDependency依赖项{get;set;}
    公共字符串GetString()
    {
    返回“Consumer of”+Dependency.GetName();
    }
    }
    [测试方法]
    公共void MyTestMethod()
    {
    var container=新容器();
    Register(c=>newconcretedependency());
    Register(c=>newconstructorexample(c.Resolve());
    Register(c=>newsetterexample(){Dependency=c.Resolve()});
    var构造函数=container.Resolve();
    AreEqual(“具体依赖项的使用者”,constructor.GetString());
    var setter=container.Resolve();
    AreEqual(“具体依赖项的使用者”,setter.GetString());
    }
    

    如果您想获得更高级的信息,我建议您获取以下信息的来源:,,。

    有什么方法可以重新打开此信息吗?@EricRomanowski:请查看以下问题被关闭的原因;如果你能在你的问题中说明这些原因,那么其他人可以投票让它重新打开,前提是他们认为它符合相关问题的标准。你不能,至少不能直接打开。但是如果其他人(有足够高的代表性)认为编辑后的答案现在是一个真正的问题,他们可以投票重新开放。或者你可以用一条自定义消息来标记它,以引起版主的注意。我重新格式化并重新表述了我的问题。对不起,
    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());
    }