我正在尝试手动推出自己的IoC工具。
这是IoC代码的一部分:
public static object Resolve(Type contract)
{
Type Implementation = typeSettings[contract];
ConstructorInfo constructor = Implementation.GetConstructors()[0];
ParameterInfo[] constructorParam = constructor.GetParameters();
if (constructorParam.Length == 0)
Activator.CreateInstance(Implementation);
List<object> paramList = new List<object>(constructorParam.Length);
foreach(ParameterInfo param in constructorParam)
paramList.Add(Resolve(param.ParameterType));
return constructor.Invoke(paramList.ToArray());
}
我想返回泛型T的对象。我无法做到。
我也无法对它进行类型转换。我只使用一个具有两个依赖项的接口。
(IPredictingFuture
,EartAndSkyPrediction
,BadConnections
)
我试图将它类型化为接口类型。 (为了访问我的客户端代码中的方法。)但这也没有用。
我错过了什么?
答案 0 :(得分:1)
在您的方法中,contract
仅在运行时已知,因此无法在编译时使用。根据您的调用者,您可以将其更改为泛型类型参数,在这种情况下您可以执行以下操作:
public static object Resolve(Type contract)
{
Type Implementation = typeSettings[contract];
ConstructorInfo constructor = Implementation.GetConstructors()[0];
ParameterInfo[] constructorParam = constructor.GetParameters();
if (constructorParam.Length == 0)
Activator.CreateInstance(Implementation);
List<object> paramList = new List<object>(constructorParam.Length);
foreach(ParameterInfo param in constructorParam)
paramList.Add(Resolve(param.ParameterType));
return constructor.Invoke(paramList.ToArray());
}
public static T Resolve<T>()
{
return (T)Resolve(typeof(T));
}
重载是因为正如你所提到的那样,Resolve(Type)
以递归方式调用自身,而泛型版本不能像那样调用它自己。
答案 1 :(得分:0)
调整此场地的命名空间,我已经使用了多年......
using System;
using System.Collections.Generic;
using DataAccess.Core.DataInterfaces;
using DataAccess.Core.Utils;
namespace StackOverflowExample
{
public class SimpleIoC<T>
{
public T getInstance()
{
return getInstance(null);
}
public T getInstance(object[] initializationParameters)
{
Type type = Activator.CreateInstance(typeof(T), initializationParameters).GetType();
// Any special initialization for an object should be placed in a case statement
// using that object's type name
switch (type.ToString())
{
// Example
//case "DataAccess.Data.ApplicantDao":
// // - Do pre-instanciation initialization stuff here -
// return (T)Activator.CreateInstance(typeof(T), initializationParameters);
default:
return (T)Activator.CreateInstance(typeof(T), initializationParameters);
}
}
}
}
不确定这个是否会对您有所帮助,但我将其用作业务规则评估引擎的一部分......
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
namespace StackOverflowExample
{
public static class DynamicObjectFactory
{
private static readonly object _lock = new object();
public static object getInstance(string assemblyName, string className)
{
Monitor.Enter(_lock);
try
{
System.Reflection.Assembly asm = System.Reflection.Assembly.Load(assemblyName);
return asm.CreateInstance(className, false, System.Reflection.BindingFlags.CreateInstance, null, null, null, null);
}
finally
{
Monitor.Exit(_lock);
}
}
public static object getInstance(string assemblyName, string className, object[] constructorParameters)
{
Monitor.Enter(_lock);
try
{
System.Reflection.Assembly asm = System.Reflection.Assembly.Load(assemblyName);
return asm.CreateInstance(className, false, System.Reflection.BindingFlags.CreateInstance, null, constructorParameters, null, null);
}
finally
{
Monitor.Exit(_lock);
}
}
}
}
答案 2 :(得分:0)
谢谢你们的回复。 我添加了这个重写的Resolve方法
public static T Resolve<T>() { return (T)Resolve(typeof(T)); }
现在,我正确地得到了这个类型。这是客户端代码:
IPredictingFuture predictions;
predictions = IoC.Resolve<IPredictingFuture>();
这样,预测后的智能感知就可以了。
如果任何一位读者因为试图制作一个IoC容器而遇到这个问题,我会指出这些好的链接: