从类型名称和程序集名称创建实例

4
我正在尝试使用Activator.CreateInstance(assemblyName, typeName)创建一个类,但我遇到了以下错误:

“System.TypeLoadException”类型的未经处理的异常发生在 mscorlib.dll 中

其他信息:无法从程序集“AssessmentDeepCompare,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”中加载类型“Question”。

在此示例中(导致上述错误),我正在尝试实例化继承自IAssessmentObject且位于同一程序集中的Question
public IAssessmentObject getInstance(string typeName) {
    string assemblyName = Assembly.GetAssembly(typeof (IAssessmentObject)).ToString();
    return (IAssessmentObject)Activator.CreateInstance(assemblyName, typeName);
}

当你只有类型名称而没有命名空间或程序集时,正确的实例化对象的方法是什么?

2
那么,如果你不告诉命名空间,Activator应该如何知道你想要的是X.Foo而不是Y.Foo - Sergey Berezovskiy
1
我的建议是放弃Activator并在您的应用程序中引入一些DI IOC引擎。无论如何,您都需要了解程序集和命名空间。 - nzic
2个回答

10

听起来你确实有这个程序集 - 只是没有命名空间限定的类型名称。

你可以获取程序集中的所有类型,然后从中获取类型:

var type = typeof(IAssessmentObject).Assembly
                                    .GetTypes()
                                    .Single(t => t.Name == "Question");
var instance = (IAssessmentObject) Activator.CreateInstance(type);

这正是我在发布问题后不久所做的。谢谢Jon。 - bflemi3

1
如果您拥有程序集名称、类型名称以及它们所在的文件夹,则可以这样做。我构建了这个功能,以根据配置文件中的选择返回一个日志记录类。
string _assemblyName = ConfigurationManager.AppSettings["MailLogger.AssemblyName"];
string _className = ConfigurationManager.AppSettings["MailLogger.ClassName"];
string _assemblyPath = ConfigurationManager.AppSettings["Reporting.Assembly.Folder"];

if (string.IsNullOrWhiteSpace(_assemblyName) || string.IsNullOrWhiteSpace(_className))
    throw new ApplicationException("Missing configuration data for the Logger.");

Assembly _loggingAssembly = Assembly.LoadFrom(System.IO.Path.Combine(_assemblyPath, _assemblyName));
ILogger _logger = _loggingAssembly.CreateInstance(_className) as ILogger;

if (_logger == null)
    throw new ApplicationException(
            string.Format("Unable to instantiate ILogger instance from {0}/{1}", _assemblyName, _className));

return _logger;

如果你没有程序集名称,我不确定如何通过反射来创建它。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接