Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/271.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/asp.net/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/93.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何用新方法动态扩展C#类_C#_Asp.net_Dynamic - Fatal编程技术网

如何用新方法动态扩展C#类

如何用新方法动态扩展C#类,c#,asp.net,dynamic,C#,Asp.net,Dynamic,我正在ASP.NET中建立一个网站,允许基于公共类创建新模块。新模块需要能够使用自己的方法/函数库扩展基类。我想在应用程序启动时加载所有模块。它们由唯一的字符串键标识 结构是这样的: root -Bin --module1.dll --module2.dll -Modules --module1 ---mod.key1 --module2 ---mod.key2 根 -垃圾箱 --module1.dll --module2.dll -模块 --模块1 ---mod.key1 --模块

我正在ASP.NET中建立一个网站,允许基于公共类创建新模块。新模块需要能够使用自己的方法/函数库扩展基类。我想在应用程序启动时加载所有模块。它们由唯一的字符串键标识

结构是这样的:

root -Bin --module1.dll --module2.dll -Modules --module1 ---mod.key1 --module2 ---mod.key2 根 -垃圾箱 --module1.dll --module2.dll -模块 --模块1 ---mod.key1 --模块2 ---mod.key2
在启动时,读取每个模块文件夹并识别其密钥,从db加载所有设置并设置公共属性,然后将其存储在集合中。当为模块请求页面时,基本页面类使用其唯一的目录键加载相应的模块。问题是基本模块类不包含特定于该模块的方法库(只包含从db加载的属性/设置)。如何在启动时加载模块期间扩展模块类以包含方法,或者仅使用其字符串名称动态实例化正确的扩展类?还有其他想法吗?我不想在app load方法中硬编码类名,这样它就可以为将来添加的模块进行扩展。

有几种方法可以做到这一点。一种方法是创建要从中继承的基类或接口,在另一个DLL中写入子类,然后根据需要使用
Assembly.LoadFrom()
方法从DLL中加载适当的类

public MyType LoadTypeFromAssembly(string assemblyPath, string typeName)
{
            var assembly = Assembly.LoadFrom(assemblyPath);

            if (assembly == null)
                throw new InvalidOperationException("Could not load the specified assembly '" + assemblyPath + "'");

            var type = assembly.GetType(typeName);
            if (type == null)
                throw new InvalidOperationException("The specified class '" + typeName + "' was not found in assembly '" + assemblyPath  + "'");

            var instance = (MyType)Activator.CreateInstance(type);
            return instance;
}

其中,
MyType
是基类或接口的类型,
typeName
是继承自MyType的后代类的名称。

这可能会对你有所帮助,我有一个@Robert的模型

我必须根据数据库中的条目切换到我的业务层

如果数据库中有自定义业务层dll的条目,则必须从数据库表中为自定义程序集指定的路径加载,否则必须从网站bin文件夹中的默认业务层加载类

namespace BO.Factory
    {
        public class CFactory
        {

            public static object getClassInstance(string key, params  object[] constructorArgs)
            {
                try
                {
                    string assemblyPath = null;
                    string customClassName = null;
                    DataSet objDataset = getAssemblyInfo(key);
                    if (objDataset != null && objDataset.Tables.Count > 0 && objDataset.Tables[0].Rows.Count > 0)
                    {
                        assemblyPath = objDataset.Tables[0].Rows[0]["ACA_ASSEMBLY_PATH"].ToString();
                        customClassName = objDataset.Tables[0].Rows[0]["ACA_CLASS_NAME"].ToString();
                    }

                    Assembly assembly;
                    Type type;
                    string className;

                    if (assemblyPath != null && assemblyPath != string.Empty)
                    {
                        assembly = Assembly.LoadFile(assemblyPath);
                        className = customClassName;
                    }
                    else // if no customisation
                    {
                        assembly = key.Split('.')[1].ToString() == "BO" ? typeof(Catalyst.BO.SchoolBO.CSchoolBO).Assembly : typeof(Catalyst.DAL.SchoolDAO.CSchoolDAO).Assembly;
                        className = key;
                    }

                    type = assembly.GetType(className, true, true);

                    object classInstance = constructorArgs == null ? Activator.CreateInstance(type) : Activator.CreateInstance(type, constructorArgs);
                    if (classInstance == null) throw new Exception("broke");
                    return classInstance;
                }
                catch (Exception e)
                {
                    throw (e);
                }

            }

            static DataSet getAssemblyInfo(string key)
            {
                try
                {
                    string cmdText = "SELECT ACA_ID,ACA_KEY,ACA_ASSEMBLY_PATH,ACA_CLASS_NAME "
                                    + "FROM ADM_CUSTOM_ASSEMBLY_INFO "
                                    + "WHERE ACA_KEY='" + key + "'";

                    System.Data.SqlClient.SqlCommand sqlcommand = new System.Data.SqlClient.SqlCommand(cmdText);

                    DAL.DBHelper.CDBHelper objCDBHelper = new Catalyst.DAL.DBHelper.CDBHelper();

                    return objCDBHelper.PopulateDS(sqlcommand);
                }
                catch
                {
                    return null;
                }

            }
        }
    }

我的默认类和自定义类都继承自一个公共接口,该接口与其中定义的所有公共方法相同。

酷,我会尝试一下,然后我需要在代码中使用它,比如MyDerivedType derivedType=(MyDerivedType)MyCollection[“my.key”];derivedType.MyMethod();似乎可以工作,但它需要一个用于构造函数参数的选项@罗伯特,这能在中等信任度下运行吗?基于和,它应该。