注意:所有示例代码都大大简化了。
我有一个DLL定义为:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Web;
namespace RIV.Module
{
public interface IModule
{
StringWriter ProcessRequest(HttpContext context);
string Decrypt(string interactive);
string ExecutePlayerAction(object ParamObjectFromFlash);
void LogEvent(object LoggingObjectFromFlash);
}
}
现在,在我的解决方案之外,其他开发人员可以定义具体的类并将它们放入我的应用程序的BIN文件夹中。也许是这样的:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RIV.Module;
namespace RIV.Module.Greeting
{
public class Module : IModule
{
public System.IO.StringWriter ProcessRequest(System.Web.HttpContext context)
{
//...
}
public string Decrypt(string interactive)
{
//...
}
public string ExecutePlayerAction(object ParamObjectFromFlash)
{
//...
}
public void LogEvent(object LoggingObjectFromFlash)
{
//...
}
}
}
现在,在我的应用程序中,我需要知道有一个新模块可用(我猜测是通过web.config或其他类似的东西),然后能够根据数据库Campaign表中的某些触发器调用它(映射到用于该特定广告系列的模块)。
我试图以这种方式实例化它:
var type = typeof(RIV.Module.Greeting.Module);
var obj = (RIV.Module.Greeting.Module)Activator.CreateInstance(type);
但是,编译器因为从未将引用设置为 RIV.Module.Greeting.dll 而打嗝!
我做错了什么?
答案 0 :(得分:2)
您需要使用更多反射:
Assembly.Load
someAssembly.GetType(name)
或搜索someAssembly.GetTypes()
Type
个实例传递给Activator.CreateInstance
答案 1 :(得分:1)
取代typeof(RIV.Module.Greeting.Module),尝试使用
var type = Type.GetType("RIV.Module.Greeting.Module, RIV.Module.Greeting");
(即通过将其程序集限定的名称指定为字符串来加载类型)并转换为IModule。
这种方法要求您知道模块的确切类和程序集名称(如您所写,它们可以存储在web.config中)。
或者,您可以采用完全动态的插件方法: