编写C#插件系统 [英] Writing C# Plugin System

查看:378
本文介绍了编写C#插件系统的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,试图谷歌,真的没有帮助。尝试在C#中搜索$ P $这里pvious的问题,没有什么类似/

Ok, tried google, really no help. Tried searching for previous question here, nothing similar/in C#.

我想写一个插件系统提供一定的可扩展性,以我的一个应用程序,以便有人可以编写应用程序的插件(S)不接触的主要应用程序的code(和风险打破的东西)。

I'm trying to write a plugin system to provide some extensibility to an application of mine so someone can write a plugin(s) for the application without touching the main application's code (and risk breaking something).

我已经得到了基地IPlugin书面接口(ATM,没有什么是尚未实现)

I've got the base "IPlugin" interface written (atm, nothing is implemented yet)

下面是如何我装:

public static void Load()
{
    // rawr: http://www.codeproject.com/KB/cs/c__plugin_architecture.aspx
    String[] pluginFiles = Directory.GetFiles(Plugins.PluginsDirectory, "*.dll");
    foreach (var plugin in pluginFiles)
    {
        Type objType = null;
        try
        {
            //Assembly.GetExecutingAssembly().GetName().Name
            MessageBox.Show(Directory.GetCurrentDirectory());
            Assembly asm = Assembly.Load(plugin);
            if (asm != null)
            {
                objType = asm.GetType(asm.FullName);
                if (objType != null)
                {
                    if (typeof(IPlugin).IsAssignableFrom(objType))
                    {
                        MessageBox.Show(Directory.GetCurrentDirectory());
                        IPlugin ipi = (IPlugin)Activator.CreateInstance(objType);
                        ipi.Host = Plugins.m_PluginsHost;
                        ipi.Assembly = asm;
                    }
                }
            }
        }
        catch (Exception e)
        {
            MessageBox.Show(e.ToString(), "Unhandled Exception! (Please Report!)", System.Windows.Forms.MessageBoxButtons.OK, System.Windows.Forms.MessageBoxIcon.Information);
        }
    }
}

这是暴雪的一个朋友试图帮助,但我真的不明白发生了什么事。

A friend from Blizzard tried to help but I really didn't understand what was wrong.

有关插件的文件夹结构如下:

The folder structure for plugins is the following:

\\

\\插件\\

\
\Plugins\

所有的插件在[根]目录引用名为Lab.Core.dll.dll和它不是在由于重复引用的插件目录present装载

All plugins reference a .dll called "Lab.Core.dll" in the [root] directory and it is not present in the Plugins directory because of duplicate references being loaded.

插件系统从Lab.Core.dll它也由我的可执行引用加载。键入IPlugin是Lab.Core.dll为好。 Lab.Core.dll是,正是因为命名,核心我的应用程序。

The plugin system is loaded from Lab.Core.dll which is also referenced by my executable. Type "IPlugin" is in Lab.Core.dll as well. Lab.Core.dll is, exactly as named, the core of my application.

如果您需要任何其他信息,只问。

If you need any other information, just ask.

- 谢谢提前!

编辑:

问题:为什么/那是什么例外,我得到,我怎么可能去修复呢? (原谅我,如果我听起来newbish)

Question: Why/What is that exception I'm getting and how could I go about fixing it? (Excuse me if I sound newbish)

最后编辑:

好了,所以我决定去寻找一些来源$ C ​​$ C的朋友写了一个TF2调节后,重新编写。

Ok so I decided to re-write it after looking at some source code a friend wrote for a TF2 regulator.

下面就是我和它的作品:

Here's what I got and it works:

    public class TestPlugin : IPlugin {
    #region Constructor

    public TestPlugin() {
        //
    }

    #endregion

    #region IPlugin Members

    public String Name {
        get {
            return "Test Plugin";
        }
    }

    public String Version {
        get {
            return "1.0.0";
        }
    }

    public String Author {
        get {
            return "Zack";
        }
    }

    public Boolean OnLoad() {
        MessageBox.Show("Loaded!");
        return true;
    }

    public Boolean OnAllLoaded() {
        MessageBox.Show("All loaded!");
        return true;
    }

    #endregion
}

        public static void Load(String file) {
        if (!File.Exists(file) || !file.EndsWith(".dll", true, null))
            return;

        Assembly asm = null;

        try {
            asm = Assembly.LoadFile(file);
        } catch (Exception) {
            // unable to load
            return;
        }

        Type pluginInfo = null;
        try {
            Type[] types = asm.GetTypes();
            Assembly core = AppDomain.CurrentDomain.GetAssemblies().Single(x => x.GetName().Name.Equals("Lab.Core"));
            Type type = core.GetType("Lab.Core.IPlugin");
            foreach (var t in types)
                if (type.IsAssignableFrom((Type)t)) {
                    pluginInfo = t;
                    break;
                }

            if (pluginInfo != null) {
                Object o = Activator.CreateInstance(pluginInfo);
                IPlugin plugin = (IPlugin)o;
                Plugins.Register(plugin);
            }
        } catch (Exception) {
        }
    }

    public static void LoadAll() {
        String[] files = Directory.GetFiles("./Plugins/", "*.dll");
        foreach (var s in files)
            Load(Path.Combine(Environment.CurrentDirectory, s));

        for (Int32 i = 0; i < Plugins.List.Count; ++i) {
            IPlugin p = Plugins.List.ElementAt(i);
            try {
                if (!p.OnAllLoaded()) {
                    Plugins.List.RemoveAt(i);
                    --i;
                }
            } catch (Exception) {
                Plugins.List.RemoveAt(i);
                --i;
            }
        }
    }


编辑:哇,在这个问题上的看法15K


Wow, 15K views on this question.

推荐答案

这听起来像你有一个循环引用。你说你的插件引用Lab.Core.DLL,但你也说了插件从Lab.Core.DLL加载。

It sounds like you have a circular reference. You said your plugins reference Lab.Core.DLL, but you also say the plugins are loaded from Lab.Core.DLL.

我误解这里发​​生了什么?

Am I misunderstanding what is happening here?

编辑:OK,现在你已经添加你的问题的问题...

OK now that you have added your question to the question...

您需要有Lab.Core.DLL访问插件被加载,因为它是一个依赖。通常情况下,这将意味着有它在同一目录或在GAC中。

You need to have Lab.Core.DLL accessible to the plugin being loaded since it is a dependency. Normally that would mean having it in the same directory or in the GAC.

我怀疑有在这里打球更深层次的设计问题,但这是立即解决问题。

I suspect there are deeper design issues at play here, but this is your immediate problem.

这篇关于编写C#插件系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆