如何用新方法动态扩展c#类
本文关键字:扩展 动态 何用 新方法 | 更新日期: 2023-09-27 18:10:45
我正在ASP中构建一个网站。NET允许基于公共类创建新模块。新模块需要能够用自己的方法/函数库扩展基类。我想在Application_Start加载所有模块。它们由一个唯一的字符串键来标识。
结构如下:
<>之前根本——module1.dll——module2.dll模块——module1——mod.key1——module2——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;
}
}
}
}
我的默认类和自定义类都继承自一个公共接口,作为其中定义的所有公共方法。