UserControl插件没有显示在页面上
本文关键字:显示 插件 UserControl | 更新日期: 2023-09-27 18:11:44
我正在研究一些usercontrol插件系统,所以可以将一个dll添加到目录中,并且usercontrol在指定的页面上是可见的。
当我将控件加载到页面时,什么也没有显示!
下面是显示的一些代码,simpletestcontrol在dll中编译并在PluginFactory中读取。(我删除或更改了一些代码,以尝试更容易阅读。)
在Default.aspx.cs中插件是可用的,我看到当我调试控件加载时。但是当我在pluingrid(一个div)中设置它时,当我运行网站时没有显示任何东西……我错过了什么?
SimpleTestControl.ascx.cs:
public partial class SimpleTest : BasePluginControl
{
public SimpleTest()
: base(Type.Test)
{
}
}
SimpleTestControl.ascx:
<%@ Control Language="C#" AutoEventWireup="true" CodeFile="simpletest.ascx.cs" Inherits="simpletest" %>
TESTESTETS
<asp:Button ID="Button1" runat="server" Text="testButton"/>
BasePluginControl.cs:
public abstract class BasePluginControl : UserControl
{
public string Name { get; set; }
public PluginType Type { get; set; }
}
Default.aspx.cs
public partial class Default : System.Web.UI.Page
{
protected override void OnInit(EventArgs e)
{
BasePluginControl plugin =
PluginFactory.GetPluginByType(PluginType.Test);
PluginGrid.Controls.Clear();
if (plugin != null)
{
PluginGrid.Controls.Add(plugin);
}
base.OnInit(e);
}
PluginFactory.cs:
public static BasePluginControl GetPluginByType(PluginType pluginType)
{
BasePluginControl plugin = plugins.FirstOrDefault(p => p.PluginType == pluginType);
if(plugin== null)
throw new DllNotFoundException("A plugin of the " + pluginType.ToString() + " is not found!");
return plugin;
}
public static ICollection<BasePluginControl> LoadPlugins()
{
string path = ConfigurationManager.AppSettings["PluginPath"];
plugins.Clear();
if (!Directory.Exists(path))
return null;
string[] dllFileNames = Directory.GetFiles(path, "*.dll");
ICollection<Assembly> assemblies = new List<Assembly>(dllFileNames.Length);
foreach (string dllFile in dllFileNames)
{
AssemblyName an = AssemblyName.GetAssemblyName(dllFile);
Assembly assembly = Assembly.Load(an);
assemblies.Add(assembly);
}
IEnumerable<Type> controlPlugins = GetPluginsOf<BasePluginControl>(assemblies);
foreach (Type controlPlugin in controlPlugins)
{
BasePluginControl plugin = (BasePluginControl)Activator.CreateInstance(controlPlugin);
if (plugin != null)
plugins.Add(plugin});
}
return plugins;
}
private static IEnumerable<Type> GetPluginsOf<T>(IEnumerable<Assembly> assemblies)
{
Type pluginType = typeof(T);
ICollection<Type> pluginTypes = new List<Type>();
foreach (Assembly assembly in assemblies)
{
if (assembly != null)
{
Type[] types = assembly.GetTypes();
foreach (Type type in types)
{
if (type.IsInterface || type.IsAbstract)
{
continue;
}
else
{
if( type.GetInterface(pluginType.FullName) != null ||
(type.BaseType != null && type.BaseType.FullName != null && type.BaseType.FullName.Equals(pluginType.FullName)))
{
pluginTypes.Add(type);
}
}
}
}
}
return pluginTypes;
}
更新:当我将以下代码添加到default.aspx.cs时,strBuild变量也为空…
string strBuild;
// a string writer to write on it
using (TextWriter stringWriter = new StringWriter())
{
// a html writer
using (HtmlTextWriter renderOnMe = new HtmlTextWriter(stringWriter))
{
// now render the control inside the htm writer
pluginModel.Control.RenderControl(renderOnMe);
// here is your control rendered output.
strBuild = stringWriter.ToString();
}
}
PluginGrid.InnerHtml = strBuild;
两件事,
-
您没有将插件添加到页面控件的集合中,因此它不会在渲染循环中被处理或被绑定到页面生命周期中。您要么必须将其添加到控件的集合中,要么必须通过在插件上调用render来手动渲染它(因为它是ASP。网络控制)。
-
这可能是因为你正在加载与web应用程序在同一域的dll。
因此它不能卸载它们。一旦载入,它们就载入了。如果它们改变了,你将不得不重置应用程序池来加载新版本。
可以选择,你应该为你的插件创建一个AppDomain。然后使用FileSystemWatcher来监视插件目录。
使用文件系统监视器检查插件目录中的文件是否被添加、修改或删除。
如果更改的文件是dll,执行以下操作
On Delete:从新的AppDomain中卸载dll中的所有插件在修改:卸载和重新加载插件从应用程序域点击添加:从新的dll中加载插件