我要建Assembly.LoadFile一个可扩展的应用程序,将通过在运行时加载额外的组件()
。这些附加组件将包含像WPF资源字典(皮肤等),纯资源(的Resx),和/或插件类。该组件还可以包含任何公共类,仅资源或资源字典。
I'm building an extensible application which will load additional assemblies at runtime through Assembly.LoadFile()
. Those additional assemblies will contain things like WPF resource dictionaries (skins, etc.), plain resources (Resx), and/or plugin classes. The assembly can also contain no public classes, only resources or resource dictionaries.
我正在寻找一种方法来确定一个程序集,像一个友好的名称(如更多皮肤或集成的浏览器),组件的功能型(SkinsLibrary,SkinsLibrary | PluginLibrary等)和附加信息(如ConflictsWith(新[] {SkinsLibrary,BrowserPlugin)。
I'm looking for a way to identify an assembly, things like a friendly name (like "Additional skins" or "Integrated browser"), the functional type of an assembly (SkinsLibrary, SkinsLibrary|PluginLibrary, etc) and additional info (like ConflictsWith(new [] {"SkinsLibrary", "BrowserPlugin").
到目前为止,我使用的约定命名组件( *皮肤。*。dll的
等)。在每个装配我有一个空的,虚类,它只是一个占位符,其中包含实际的(组装范围)信息的自定义类的属性,但是这感觉就像一个黑客攻击。有一些精简,标准的方法来处理这个问题?
So far I'm using a convention in naming assemblies (*.Skins.*.dll
, etc.). In each assembly I have an empty, dummy class which is just a placeholder for custom class attributes which hold the actual (assembly-wide) information, but that feels like a hack. Is there some streamlined, standard way to handle this?
我正在开发的中央装载系统和其他开发人员在我的团队将开发这些额外的组件,所以我想尽量减少公约和管道的详细信息。
I'm developing the central loader system and other developers in my team will develop those additional assemblies, so I'd like to minimize the conventions and plumbing details.
编辑:我已经更新了一些更详细的信息,答案
下面是一个例子,如何你可能完成你想做的事情。 首先定义枚举为不同类型的插件的类型。
Here is an example how you might accomplish what you want to do. Start by defining a enum for your different types of plugin types.
public enum AssemblyPluginType
{
Skins,
Browser
}
添加将用于描述所述插件(装配插件类型和潜在的冲突)两种属性。
Add two attributes that will be used to describe the plugins (assembly plugin type and potential conflicts).
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public sealed class AssemblyPluginAttribute : Attribute
{
private readonly AssemblyPluginType _type;
public AssemblyPluginType PluginType
{
get { return _type; }
}
public AssemblyPluginAttribute(AssemblyPluginType type)
{
_type = type;
}
}
[AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)]
public sealed class AssemblyPluginConflictAttribute : Attribute
{
private readonly AssemblyPluginType[] _conflicts;
public AssemblyPluginType[] Conflicts
{
get { return _conflicts; }
}
public AssemblyPluginConflictAttribute(params AssemblyPluginType[] conflicts)
{
_conflicts = conflicts;
}
}
现在你可以将这些属性添加到您的程序集。
Now you can add these attributes to your assembly.
下面两行可以在任何地方,在组装,只要他们是一个命名空间之外增加。我通常把装配在的AssemblyInfo.cs
文件,该文件可以在属性
文件夹中找到的属性。
The following two lines can be added anywhere in the assembly as long as they're outside a namespace. I usually put assembly attributes in the AssemblyInfo.cs
file that can be found in the Properties
folder.
[assembly: AssemblyPluginAttribute(AssemblyPluginType.Browser)]
[assembly: AssemblyPluginConflictAttribute(AssemblyPluginType.Skins, AssemblyPluginType.Browser)]
现在你可以使用下面的code,以检查特定属性的组件:
Now you can use the following code to examine an assembly for specific attributes:
using System;
using System.Reflection;
namespace ConsoleApplication
{
public class Program
{
public static void Main(string[] args)
{
// Get the assembly we're going to check for attributes.
// You will want to load the assemblies you want to check at runtime.
Assembly assembly = typeof(Program).Assembly;
// Get all assembly plugin attributes that the assembly contains.
object[] attributes = assembly.GetCustomAttributes(typeof(AssemblyPluginAttribute), false);
if (attributes.Length == 1)
{
// Cast the attribute and get the assembly plugin type from it.
var attribute = attributes[0] as AssemblyPluginAttribute;
AssemblyPluginType pluginType = attribute.PluginType;
}
}
}
}