我有一个项目正在处理,我不知道在编译时需要实例化哪个类。我正在尝试使用Activator.CreateInstance()根据用户输入为我生成一个新类。下面的代码运行良好,但我必须将我的INECCQuery类上的构造函数更改为只有一个默认构造函数,而不是使用任何类型的依赖注入。有没有办法我仍然可以使用我的注射绑定和Activator.CreatInstance()?我正在使用Ninject进行注射。
[HttpGet]
public ActionResult Index(string item) {
Type t = Type.GetType(string.Format("Info.Audit.Query.{0}Query, Info.Audit", item.ToUpper()));
if (t != null) {
INECCQuery query = (INECCQuery)Activator.CreateInstance(t);
var results = query.Check();
return View("Index", results);
}
return View("Notfound");
}
答案 0 :(得分:3)
在可能的情况下,始终首选构造函数注入,但合适的备份将是利用属性注入。
http://ninject.codeplex.com/wikipage?title=Injection%20Patterns
class SomeController {
[Inject]
public Object InjectedProperty { get; set; }
}
基于您尝试替换Activator.CreateInstance
的假设,您可以注入Func<T, INECCQuery>
或您想要使用的任何工厂。
答案 1 :(得分:3)
您可以让Ninject在运行时为您提供类型为t的对象,并且仍然可以通过构造函数获取依赖注入....我在我的应用程序中为一个案例做了类似的事情。
在Global.asax.cs文件中,我有以下方法:
/// <summary>
/// Gets the instance of Type T from the Ninject Kernel
/// </summary>
/// <typeparam name="T">The Type which is requested</typeparam>
/// <returns>An instance of Type T from the Kernel</returns>
public static T GetInstance<T>()
{
return (T)Kernel.Get(typeof(T));
}
这取决于静态内核引用。
然后,在代码中,我做
var myInfrastructureObject = <YourAppNameHere>.GetInstance<MyInfrastructureType>();
所以,我知道编译时的类型,而你没有,但改变它并不困难。
您可能还希望查看ServiceLocator模式。
答案 2 :(得分:0)
我实际上发现你可以向Activator.CreateInstance
方法传递第二个选项,只要它与你的构造函数签名匹配就可以了。唯一的问题是如果您的参数不匹配,您将收到运行时错误。
Type t = Type.GetType(string.Format("Info.Audit.Query.{0}Query, Info.Audit", item.ToUpper()));
INECCQuery query = (INECCQuery)Activator.CreateInstance(t, repository);
感谢您的帮助。