【发布时间】:2011-12-07 00:01:41
【问题描述】:
背景
为了帮助提高我对 IOC 以及如何使用它的理解,我想创建一个所有三种 IOC 技术的示例:构造函数注入、Setter 注入和接口注入,而无需使用第三方框架。我想我有一个构造函数注入的基本示例,但在设置器和接口注入方面遇到了困难。
我的问题
您将如何从头开始处理编写界面和 setter 注入?
这是我的想法,如果我走在正确的轨道上,请告诉我。
接口注入:
- 循环遍历使用构造函数注入实例化的解析对象,检查 interfaceDependencyMap 中实现了哪些接口
- 定义某种 interfaceDependencyMap 以将接口与实现相关联。
- 使用 interfaceDependencyMap 解决实现
- 为使用构造函数注入初始化的对象分配适当的属性
Setter 注入:
- 循环遍历使用构造函数注入实例化的解析对象
- 定义某种 setterInjectionMap
- 使用构造函数映射从 MethodInfo 解析预期参数
- 调用setter方法传入解析的参数对象
这是我到目前为止的构造函数注入
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));
}
}
【问题讨论】:
-
有什么办法可以重新打开这个吗?
-
@EricRomanowski:请参阅以下原因,了解问题为何被关闭;如果您可以在问题中解决这些原因,那么其他人可以投票重新开放它,前提是他们认为它符合 SO 问题的标准。
-
你不能,至少不能直接。但是,如果其他人(具有足够高的代表)认为编辑后的答案现在是一个真正的问题,他们可以投票重新开放。或者您可以使用自定义消息将其标记为版主注意。
-
我重新格式化并重新表述了我的问题。抱歉,我在背景信息中暗示了一个问题。
-
显然这是 c# 最保守的秘密 =)
标签: c# inversion-of-control ioc-container