c# - 使用 Reflection 为网站创建可扩展图表
问题描述
我正在尝试实现一个网站,只需将 DLL 放入文件夹即可添加新图表。在撰写本文时,尚不清楚需要哪些图表,这提供了一种部署新图表的简单方法,而无需重新部署整个网站。我正在使用 Google Charts 来提供 Google 功能,并且将显示每个图表每种类型的图表都继承自以下接口 public enum ChartType { BAR, COLUMN, PIE, TABLE }
public class DataColumn
{
public String ColumnType { get; set; }
public String ColumnValue { get; set; }
}
public interface IChart
{
/// <summary>
/// Dictionary of Columns, Each column is defined as a type and title
/// </summary>
List<DataColumn> Columns { get; set; }
/// <summary>
/// ChartType, What type of Chart; possible values BAR, COLUMN, PIE, TABLE
/// </summary>
ChartType ChartType { get; }
/// <summary>
/// Data - data for the chart
/// </summary>
String Data { get; }
/// <summary>
/// Name of the chart, must be unique used to identify each chart stub
/// </summary>
String Name { get; }
/// <summary>
/// Title - the title that will be displayed above the chart
/// </summary>
String Title { get; }
/// <summary>
/// What position will the legend of there is one.
/// </summary>
String LegendPosition { get; }
}
下面使用上面的接口
public class ReferralDownloadCount : IChart, IDisposable
{
List<ChartDemo.DataColumn> columns = null;
public ReferralDownloadCount()
{
columns = new List<ChartDemo.DataColumn>()
{
new ChartDemo.DataColumn() { ColumnType = "String" , ColumnValue = "Date" },
new ChartDemo.DataColumn() { ColumnType = "Number" , ColumnValue = "Referral Count"}
};
}
/// <summary>
/// Returns the chart data
/// </summary>
public String Data
{
get
{
String sql = String.Empty;
String jsonResult = String.Empty;
DataSet ds = null;
DataTable dt = null;
List<ReferralCountData> results = null;
JsonSerializer serializer = null;
try
{
sql = "Select * From[Portal].[ReferralCount] Where DATEDIFF(d, [Download Date], Convert(Date, GETDATE())) < 8 Order By[Download Date] Asc";
ds = DataToolbox.Execute(new SqlConnection(Properties.Settings.Default.DataConnection), sql, CommandType.Text);
if (ds.Tables.Count > 0)
{
dt = ds.Tables[0]; // we really are only expecting one table
results = new List<ReferralCountData>();
serializer = new JsonSerializer();
serializer.Converters.Add(new JavaScriptDateTimeConverter());
foreach ( DataRow dr in dt.Rows)
{
using (ReferralCountData rcd = new ReferralCountData()
{
Label = ((System.DateTime)dr.ItemArray[0]).ToString("dd/MM/yyyy"),
Value = Convert.ToInt32(dr["Referral Count"])
})
{
results.Add(rcd);
}
}
jsonResult = JsonConvert.SerializeObject(results);
}
}
catch ( System.Exception ex)
{
throw ex;
}
finally
{
}
return jsonResult;
}
}
public List<ChartDemo.DataColumn> Columns {
get
{
return columns;
}
set
{
columns = value;
}
}
public ChartType ChartType => ChartType.COLUMN;
public string Name => "REFERRALCOUNT";
public string Title => "Referral Download Count";
public string LegendPosition => "None";
public void Dispose()
{
}
}
该站点遍历包含 DLL 的目录,并搜索任何类(例如上面的类)以创建图表 然后提取从 IChart 继承的类,因为 GetChartPlugins 检查每个 DLL
static List<IChart> GetChartPlugins(List<Assembly> assemblies)
{
List<Type> availableTypes = new List<Type>();
List<Type> alertList = null;
try
{
foreach (Assembly currentAssembly in assemblies)
availableTypes.AddRange(currentAssembly.GetTypes());
alertList = availableTypes.FindAll(delegate (Type t)
{
List<Type> interfaceTypes = new List<Type>(t.GetInterfaces());
return interfaceTypes.Contains(typeof(IChart));
});
}
catch (ReflectionTypeLoadException ex)
{
StringBuilder sb = new StringBuilder();
foreach (Exception exSub in ex.LoaderExceptions)
{
sb.AppendLine(exSub.Message);
FileNotFoundException exFileNotFound = exSub as FileNotFoundException;
if (exFileNotFound != null)
{
if (!string.IsNullOrEmpty(exFileNotFound.FusionLog))
{
sb.AppendLine("Fusion Log:");
sb.AppendLine(exFileNotFound.FusionLog);
}
}
sb.AppendLine();
}
string errorMessage = sb.ToString();
}
catch ( System.Exception ex)
{
throw ex;
}
finally
{
}
// convert the list of Objects to an instantiated list of ICalculators
return alertList.ConvertAll<IChart>(delegate (Type t) { return Activator.CreateInstance(t) as IChart; });
}
但是,当它运行时,尝试调用 currentAssembly.GetTypes() 时会抛出一个 ReflectionTypeLoadException 最终变成;
来自程序集“ReferralManagementCharts,Version=1.0.0.0,Culture=neutral,PublicKeyToken=null”的“ReferralManagementCharts.ReferralDownloadCount”类型中的方法“get_Columns”没有实现。任何人都可以看到为什么因为 ReferralDownlodCount 的 Columns 属性
public List<ChartDemo.DataColumn> Columns {
get
{
return columns;
}
set
{
columns = value;
}
}
有得到。
解决方案
推荐阅读
- docker - 在 Docker 容器中安装 node_modules 并与主机同步
- visual-studio - Windbg 内核调试器显示在 VS2015 和 VS2017 中编译的 C++ x64 应用程序的错误用户模式堆栈
- python - 使用 OpenCV 从图像中识别地标和裁剪嘴的脚本看不到人脸
- r - Shiny - observeEvent 无需点击即可出现
- excel - 在 Excel 上从单行创建唯一的 SKU 行
- vba - 计算过去和未来数据的正数和负数
- c++ - 从 C++ 中的对象获取数组
- maven - 如何将 jars 上传到 Nexus?
- c# - 如何使用 OPCFoundation.NetStandard.Opc.Ua 检索 OPC 项目
- batch-file - windows - 使用批处理文件更改 REG_SZ reg 值