我正在使用某个usercontrol插件系统,因此可以将dll添加到目录中,并且用户控件在指定页面上可见。
当我将控件加载到页面时,没有显示任何内容!
下面是一些显示的代码,simpletestcontrol在dll中编译并在PluginFactory中读取。 (我删除或更改了一些代码以尝试制作更容易阅读。)
在Default.aspx.cs中插件可用,我看到我调试时控件已加载..但是当我在PluginGrid(一个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;
答案 0 :(得分:0)
两件事,
您没有将插件添加到页面控件的集合中,因此它不会在渲染循环中处理或者被绑定到页面生命周期中。你必须将它添加到控件的集合中,或者你必须通过调用插件上的Render来手动渲染它(因为它是一个ASP.Net控件)。
您可能正在将dll加载到与Web应用程序相同的域中。
因此无法卸载它们。加载后,它们就会被加载。如果他们更改,您将不得不重置应用程序池以加载新版本。
或者,您应该为插件创建AppDomain。然后使用FileSystemWatcher监视插件目录。
使用文件系统观察程序检查从插件目录添加,修改或删除文件的时间。
如果更改的文件是dll,请执行以下操作
On Delete:从新的AppDomain卸载dll中的所有插件 On Modified:从App Domain卸载并重新加载插件 On Add:从新dll加载插件