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;

UserControl插件没有显示在页面上

两件事,

  1. 您没有将插件添加到页面控件的集合中,因此它不会在渲染循环中被处理或被绑定到页面生命周期中。您要么必须将其添加到控件的集合中,要么必须通过在插件上调用render来手动渲染它(因为它是ASP。网络控制)。

  2. 这可能是因为你正在加载与web应用程序在同一域的dll。

因此它不能卸载它们。一旦载入,它们就载入了。如果它们改变了,你将不得不重置应用程序池来加载新版本。

可以选择,你应该为你的插件创建一个AppDomain。然后使用FileSystemWatcher来监视插件目录。

使用文件系统监视器检查插件目录中的文件是否被添加、修改或删除。

如果更改的文件是dll,执行以下操作

On Delete:从新的AppDomain中卸载dll中的所有插件在修改:卸载和重新加载插件从应用程序域点击添加:从新的dll中加载插件