UserControl插件未在页面上显示

时间:2014-07-05 07:23:42

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

我正在使用某个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;

1 个答案:

答案 0 :(得分:0)

两件事,

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

  2. 您可能正在将dll加载到与Web应用程序相同的域中。

  3. 因此无法卸载它们。加载后,它们就会被加载。如果他们更改,您将不得不重置应用程序池以加载新版本。

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

    使用文件系统观察程序检查从插件目录添加,修改或删除文件的时间。

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

    On Delete:从新的AppDomain卸载dll中的所有插件 On Modified:从App Domain卸载并重新加载插件 On Add:从新dll加载插件