【问题标题】:Activator.CreateInstance and NinjectActivator.CreateInstance 和 Ninject
【发布时间】:2012-06-20 00:10:30
【问题描述】:

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

【问题讨论】:

    标签: c# c#-4.0 ninject


    【解决方案1】:

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

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

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

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

    【讨论】:

    • @zespri,您如何区分Activator.CreateInstance 和“通过反射构造对象”?
    【解决方案2】:

    你可以让 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 模式。

    【讨论】:

      【解决方案3】:

      我实际上发现您可以将第二个选项传递给Activator.CreateInstance 方法,只要它与您的构造函数签名匹配,它就可以工作。唯一的问题是,如果您的参数不匹配,您将收到运行时错误。

      Type t = Type.GetType(string.Format("Info.Audit.Query.{0}Query, Info.Audit", item.ToUpper()));
      INECCQuery query = (INECCQuery)Activator.CreateInstance(t, repository);
      

      感谢大家的帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多