5

我有一个正在处理的项目,我不知道在编译时需要实例化什么类。我正在尝试使用 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");
    }
4

3 回答 3

3

在可能的情况下,始终首选构造函数注入,但合适的备份是利用属性注入。

http://ninject.codeplex.com/wikipage?title=Injection%20Patterns

class SomeController {

  [Inject]
  public Object InjectedProperty { get; set; }

}

基于您尝试替换的假设,Activator.CreateInstance您可以注入一个Func<T, INECCQuery>或任何您希望使用的工厂。

于 2012-06-20T00:34:33.080 回答
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 模式。

于 2012-06-20T10:12:10.203 回答
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);

感谢所有的帮助。

于 2012-12-13T22:40:43.567 回答