簡體   English   中英

Activator.CreateInstance-無法使用返回類型

[英]Activator.CreateInstance - Not able to use the return type

我正在嘗試手動開發自己的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的對象。我無法做到這一點。

我也不能打字。 我只使用一個具有兩個依賴項的接口。 IPredictingFutureEartAndSkyPredictionBadConnections

我正在嘗試將其類型轉換為接口類型。 (為了訪問我的客戶端代碼中的方法。)但這也不起作用。

我想念什么?

在您的方法中, 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)遞歸地調用自身,而通用版本則不能這樣調用自身。

調整該場所的名稱空間,我已經使用了多年……

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);
        }
    }
}

}

謝謝大家的回應。 我添加了此覆蓋的Resolve方法

public static T Resolve<T>() { return (T)Resolve(typeof(T)); }

現在,我正確地得到了類型。 這是客戶端代碼:

IPredictingFuture predictions;
predictions = IoC.Resolve<IPredictingFuture>();

這樣,預測后的智能感知就可以正常工作。

如果有任何讀者因為試圖煮熟IoC容器而落入這個問題,我將向他們指出以下重要鏈接:

  1. Ken的33班輪IoC
  2. 15班輪IoC by Ayende
  3. Ayende的后續帖子,介紹為什么不應該編寫自己的IoC
  4. 關於IoC容器的良好鏈接
  5. 另一個關於IoC的SO問題

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM