简体   繁体   English

如何实例化一个未包含在C#项目中的对象?

[英]How do you instantiate an object that is not included in your C# project?

Note: All sample code is greatly simplified. 注意:所有示例代码都大大简化了。

I have a DLL defined as: 我有一个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);
    }
}

Now, outside of my solution, other developers can define concrete classes and drop them into the BIN folder of my app. 现在,在我的解决方案之外,其他开发人员可以定义具体的类并将它们放入我的应用程序的BIN文件夹中。 Maybe something like: 也许是这样的:

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)
        {
            //...
        }
    }
}

Now, in my app I would need to know that a new Module was available (I am guessing via web.config or something along those lines) and then be able to call it based off of some trigger in the database Campaign table (which maps to the module to use for that specific campaign). 现在,在我的应用程序中,我需要知道一个新的模块可用(我猜通过web.config或其他类似的东西),然后能够根据数据库Campaign表中的一些触发器调用它(这些映射到用于该特定活动的模块)。

I am trying to instantiate it this way: 我试图以这种方式实例化它:

var type = typeof(RIV.Module.Greeting.Module);
var obj = (RIV.Module.Greeting.Module)Activator.CreateInstance(type);

However, the compiler belches because a reference was never set to RIV.Module.Greeting.dll ! 但是,编译器打气,因为从未将引用设置为RIV.Module.Greeting.dll

What am I doing wrong? 我究竟做错了什么?

You need to use more reflection: 你需要使用更多的反射:

  • Load the assembly by calling Assembly.Load 通过调用Assembly.Load加载程序集
  • Find the type by calling someAssembly.GetType(name) or searching someAssembly.GetTypes() 通过调用someAssembly.GetType(name)或搜索someAssembly.GetTypes()查找类型
  • Pass the Type instance to Activator.CreateInstance Type实例传递给Activator.CreateInstance
  • Cast it to your interface. 把它投射到你的界面。

Instead of typeof(RIV.Module.Greeting.Module), try using 而不是typeof(RIV.Module.Greeting.Module),尝试使用

var type = Type.GetType("RIV.Module.Greeting.Module, RIV.Module.Greeting");

(ie load the type by specifying its assembly-qualified name as string) and casting to IModule. (即通过将其程序集限定的名称指定为字符串来加载类型)并转换为IModule。

This approach requires you to know the exact class and assembly names of the modules (as you wrote, they could be stored in web.config). 这种方法要求您知道模块的确切类和程序集名称(如您所写,它们可以存储在web.config中)。

Alternatively, you could go for a completely dynamic plugin approach: 或者,您可以采用完全动态的插件方法:

  1. establish a convention that all module assemblies should be named "RIV.Module.XYZ" 建立一个所有模块程序集应命名为“RIV.Module.XYZ”的约定
  2. scan the bin directory for matching DLLs 扫描bin目录以查找匹配的DLL
  3. for each DLL, load it (eg Assembly.Load) and scan for types implementing IModule 对于每个DLL,加载它(例如Assembly.Load)并扫描实现IModule的类型
  4. instantiate all found types and cast to IModule 实例化所有找到的类型并转换为IModule

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 如何在 c# 中将 Object 转换为另一种类型? - How do you convert in c# an Object to another type? C#-如何使图表对象在X轴上从0开始? - C# - How do you make a chart object start at 0 on the X axis? 如何从C#4.0调用com对象方法 - How do you call a com object method from c# 4.0 如何将多个数据类型的数组传递给在C#4.0中声明为[in,out] SAFEARRAY(VARIANT)的COM对象? - How do you pass an array of multiple data types to a COM object declared as [in, out] SAFEARRAY(VARIANT) in C# 4.0? C#如何创建将数组作为参数传递的方法? - C# how do you create a method that passes an array as an argument? 您可以向ac#watcher添加对象吗? - Can you add an object to a c# watcher? 如何在 mongodb 内部 object 和 c# 中进行聚合排序 - How to do aggregation sort in mongodb inner object with c# C#/ ASP.NET MVC 4实例化从工厂方法中的接口派生的对象 - C#/ASP.NET MVC 4 Instantiate Object Derived From Interface In Factory Method 在C#VS2013中,如何一次一次读取资源txt文件? - In C# VS2013 how do you read a resource txt file one line at a time? 如何在C#的文本框中将插入记号更改为插入类型(闪烁的框而不是闪烁的行)? - How do you change the caret to the insert type (a flashing box instead of a flashing line) in a textbox in C#?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM