我的建议是为 SimpleIOC 创建一个扩展方法。像这样的东西:
public static T CreateInstance<T>(this SimpleIoc simpleIoc)
{
// TODO implement
}
您已经知道获取相同实例的方法;使用创建新实例的方法扩展了 SimpleIoc:
T instance = SimpleIoc.Default.GetInstance<T>();
T createdInstance = SimpleIoc.Defalt.CreateInstance<T>();
如果您不熟悉扩展方法,请参阅扩展方法揭秘
实施:
- 类型 T 的,获取构造函数。
- 如果有多个构造函数:要么抛出异常,要么决定使用哪个构造函数。简单方法:使用与 中使用的方法相同的方法,并
SimpleIoc.GetInstance
带有一个属性。更详细的方法:尝试找出是否可以找到与构造函数之一匹配的注册元素。此处不作说明。
- 找到所需的构造函数后,获取其参数。
- 向 SimpleIoc 询问此参数的实例,或者如果它们也应该是新的,请询问 SimpleIoc 创建新实例。
- 创建实例
.
public static T CreateInstance<T>(this SimpleIoc ioc)
{
return (T)ioc.CreateInstance(typeof(T));
}
public static object CreateInstance(this SimpleIoc ioc, Type type)
{
ConstructorInfo constructor = ioc.GetConstructor(type);
IEnumerable<object> constructorParameterValues = ioc.GetParameters(constructor);
constructor.Invoke(constructorParameterValues.ToArray());
}
要决定使用哪个构造函数:
private static ConstructorInfo GetConstructor(this SimpleIoc ioc, Type type)
{
ConstructorInfo[] constructors = type.GetConstructors();
ConstructorInfo constructorToUse;
if (constructorInfo.Length > 1)
{
// Decide which constructor to use; not explained here
// use Attribute like SimpleIoc.GetInstance?
// other method: use SimpleIoc.IsRegistered to check which Parameters
// are registered: use ConstructorInfo.GetParameters()
constructorToUse =
}
else
constructorToUse = constructoInfo[0];
return constructorToUse;
}
要在构造函数中获取参数的值,我们需要决定是要来自 Ioc 的现有值,还是创建新值:
public static IEnumerable<object> GetParameterValues(this simpleIoc ioc,
ConstructorInfo constructor)
{
IEnumerable<Type> parameterTypes = contructor.GetParameters()
.Select(parameter => parameter.ParameterType);
return ioc.GetInstances(parameterTypes);
}
public static IEnumerable<object> GetInstances(this SimpleIoc ioc,
IEnumerable<Type> types)
{
// TODO: decide if we want an existing instance from ioc,
// or a new one
// use existing instance:
return types.Select(type => ioc.GetInstance(type));
// or create a new instance:
return types.Select(type => ioc.CreateInstance(type));
}
这似乎有很多代码,但其中大部分是注释,大多数方法都是一个衬里。