【问题标题】:UserControl plugin not showing on pageUserControl 插件未显示在页面上
【发布时间】:2014-07-05 07:23:41
【问题描述】:

我正在开发一些用户控件插件系统,因此可以将 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; }
}

默认.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);
    }

插件工厂.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;

【问题讨论】:

    标签: c# asp.net plugins dll user-controls


    【解决方案1】:

    两件事,

    1. 您没有将插件添加到页面控件的集合中,因此它不会在渲染循环中进行处理或与页面生命周期相关联。您要么必须将其添加到控件的集合中,要么必须通过在插件上调用 Render 手动呈现它(因为它是一个 ASP.Net 控件)。

    2. 这可能是因为您将 dll 加载到与 Web 应用程序相同的域中。

    因此它无法卸载它们。一旦加载,它们就会被加载。如果它们发生变化,您将不得不重置应用程序池以加载新版本。

    或者,您应该为您的插件创建一个 AppDomain。然后使用 FileSystemWatcher 监控插件目录。

    使用文件系统观察器检查何时从插件目录添加、修改或删除文件。

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

    删除时:从新 AppDomain 的 dll 中卸载所有插件 修改后:从应用程序域卸载并重新加载插件 添加时:从新的 dll 加载插件

    【讨论】:

    • 我希望添加这一行“this.Page.Controls.Add(plugin);”在 Default.aspx.cs 中工作......但我想我错过了什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-09
    • 1970-01-01
    相关资源
    最近更新 更多