[英]C#: use “Class Library” Project for plugins
this question follows my previous question . 这个问题遵循我之前的问题 。 I have ac# ASP.NET application and i want to provide support for plugins. 我有ac#ASP.NET应用程序,我想为插件提供支持。 Plugins can be custom c# classes, javascript, html, css, images, etc. 插件可以是自定义c#类,javascript,html,css,图像等。
I see no problem as long as my application is extended with c# classes because all the user has to do is create a new "class library" project in visual studio and implement the interfaces, i provide. 只要我的应用程序使用c#类扩展,我就没有问题,因为所有用户必须做的是在visual studio中创建一个新的“类库”项目并实现我提供的接口。 Then build a dll out of it and upload it to my server. 然后从中构建一个DLL并将其上传到我的服务器。 The plugin-developer can add static files (html, js, css, etc.) into this project as well but i found some problems with that: 插件开发人员也可以将静态文件(html,js,css等)添加到这个项目中,但我发现了一些问题:
So i am starting to question the "class library" project type is right for my needs. 所以我开始质疑“类库”项目类型是否适合我的需求。 Is there a way to get around of my issues or do i have to use another project type? 有办法解决我的问题,还是我必须使用其他项目类型?
Thank you for any help! 感谢您的任何帮助!
Edit: Changed the question a little bit so it is better to understand. 编辑:稍微改变了一下这个问题,这样可以更好地理解。
You could make a zip package with the plugin dll and files. 你可以使用插件dll和文件制作一个zip包。 NuGet also uses this mechanism. NuGet也使用这种机制。 A .nupkg is also just a zip file. .nupkg也只是一个zip文件。
I would start by looking at MEF (Managed Extensibility Framework). 我首先看一下MEF(Managed Extensibility Framework)。
MSDN information can be found here: https://msdn.microsoft.com/en-us/library/dd460648(v=vs.110).aspx MSDN信息可以在这里找到: https : //msdn.microsoft.com/en-us/library/dd460648(v = vs.110).aspx
From that link you can get more information and I believe there is a tutorial as well. 从该链接可以获得更多信息,我相信还有一个教程。
Oh, for me it seems very simple. 哦,对我来说似乎很简单。
extras
让开发人员创建插件自由式并将所有其他文件放在一个目录中,让我们称之为extras
extras
directory and add it to the ClassLibrary project as EmbeddedResource. 该脚本将从extras
目录创建zip存档,并将其作为EmbeddedResource添加到ClassLibrary项目中。 The best idea would be to provide project template with script included, and also the empty zip archive added as embedded resource (it will be easier to just pack the files in the script and replace the file), and pre-build action set to run the script. 最好的想法是提供包含脚本的项目模板,以及作为嵌入式资源添加的空zip存档(将脚本中的文件打包并替换文件将更容易),以及预构建操作集以运行剧本。
Am I missing something? 我错过了什么吗?
What about this. 那这个呢。
In your web application, you could add a function that loop into your plugin directory and find DLL implementing an Iplugin (name is up to you) interface. 在您的Web应用程序中,您可以添加一个循环到您的插件目录中的函数,并找到实现Iplugin(名称取决于您)接口的DLL。
The interface is defined in a class library that both your web application and plugins have to implement. 接口在类库中定义,您的Web应用程序和插件都必须实现。
You can use the Httpcontext Server mappath to read javascript and other files. 您可以使用Httpcontext Server mappath来读取javascript和其他文件。
Here is a very basic implementation 这是一个非常基本的实现
First, you have the plugin interface (a class library implemented both by the web application and the individual plugins) I implemented sample properties and methods... 首先,你有插件接口(由Web应用程序和各个插件实现的类库)我实现了样本属性和方法......
using System.Web;
public interface IPlugin
{
string Name { get; set; }
string Output { get; set; }
void Load(ref httpcontext Context);
void Dispose();
void Display();
}
Next, you have the Actual plugin class library we want to implement. 接下来,您有我们想要实现的Actual插件类库。
using System.Web;
using IPlugins;
public class AwesomePlugin : IPlugins.IPlugin
{
private string _Name = "AwesomePlugin";
private HttpContext _Context;
public string Name {
get { return _Name; }
set { _Name = value; }
}
public string Output {
get { return "Yay !!!"; }
set {
throw new NotImplementedException();
}
}
public void Display()
{
throw new NotImplementedException();
}
public void Dispose()
{
throw new NotImplementedException();
}
public void Load(ref Web.HttpContext Context)
{
}
}
Finally, you dynamically load your plugins so you can use them in your application. 最后,您可以动态加载插件,以便在应用程序中使用它们。
private Dictionary<string, IPlugins.IPlugin> _Plugins = new Dictionary<string, IPlugins.IPlugin>();
public void LoadPlugins()
{
lock (static_LoadPlugins_IpluginType_Init) {
try {
if (InitStaticVariableHelper(static_LoadPlugins_IpluginType_Init)) {
static_LoadPlugins_IpluginType = typeof(IPlugins.IPlugin);
}
} finally {
static_LoadPlugins_IpluginType_Init.State = 1;
}
}
string ServerPath = HttpContext.Current.Server.MapPath("~") + "Plugins";
dynamic Plugins = io.Directory.GetFiles(ServerPath);
foreach (string PluginPath in Plugins) {
dynamic Assembly = system.Reflection.Assembly.LoadFile(PluginPath);
Type PluginClass = Assembly.GetTypes.Where(T => T.GetInterface("IPlugin") != null).First;
IPlugins.IPlugin MyPlugin = Activator.CreateInstance(PluginClass);
MyPlugin.Load(httpcontext.Current);
_Plugins.@add(PluginClass.ToString, MyPlugin);
}
}
static bool InitStaticVariableHelper(Microsoft.VisualBasic.CompilerServices.StaticLocalInitFlag flag)
{
if (flag.State == 0) {
flag.State = 2;
return true;
} else if (flag.State == 2) {
throw new Microsoft.VisualBasic.CompilerServices.IncompleteInitialization();
} else {
return false;
}
}
That way, you can implement whatever you want in your plugin. 这样,您就可以在插件中实现您想要的任何内容。 I believe you could load your plugins in a separate appdomain with restricted permissions to everything. 我相信你可以在一个单独的appdomain中加载你的插件,对所有内容都有限制权限。
The files (Javascript / CSS / Html) should be available by accessing the full path of the file. 通过访问文件的完整路径,应该可以使用文件(Javascript / CSS / Html)。
string ServerPath = HttpContext.Current.Server.MapPath("~") + "Plugins";
If the resources is embedded into the plugin DLL, you could read the stream from the loaded assembly or let the plugin manage its own embedded files. 如果资源嵌入到插件DLL中,您可以从加载的程序集中读取流,或让插件管理自己的嵌入文件。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.