.Net 4 – 在程序集中包含自定义信息

我正在构建一个可扩展的应用程序,它将在运行时通过Assembly.LoadFile()加载其他程序集。 这些附加程序集将包含诸如WPF资源字典(皮肤等),普通资源(Resx)和/或插件类之类的东西。 程序集也可以不包含公共类,只包含资源或资源字典。

我正在寻找一种识别程序集的方法,如友好名称(如“附加外观”或“集成浏览器”),程序集的function类型(SkinsLibrary,SkinsLibrary | PluginLibrary等)和其他信息(如ConflictsWith(new [] {“SkinsLibrary”,“BrowserPlugin”)。

到目前为止,我在命名程序*.Skins.*.dll使用约定( *.Skins.*.dll等)。 在每个程序集中,我有一个空的虚拟类,它只是一个占位符,用于保存实际(程序集范围)信息的自定义类属性,但这感觉就像一个黑客。 是否有一些简化的标准方法来处理这个问题?

我正在开发中央加载器系统,我团队中的其他开发人员将开发这些额外的程序集,所以我想最小化约定和管道细节。

编辑:我已经用更详细的信息更新了答案。

这是一个如何完成您想要做的事情的示例。
首先为不同类型的插件类型定义枚举。

 public enum AssemblyPluginType { Skins, Browser } 

添加两个将用于描述插件的属性(程序集插件类型和潜在冲突)。

 [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; } } 

现在,您可以将这些属性添加到程序集中。

只要它们位于命名空间之外,就可以在程序集中的任何位置添加以下两行。 我通常将程序集属性放在AssemblyInfo.cs文件中,该文件可以在Properties文件夹中找到。

 [assembly: AssemblyPluginAttribute(AssemblyPluginType.Browser)] [assembly: AssemblyPluginConflictAttribute(AssemblyPluginType.Skins, AssemblyPluginType.Browser)] 

现在,您可以使用以下代码检查特定属性的程序集:

 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; } } } } 

我部分获取信息但是

您可以添加自定义AssemblyInfo属性 ,您可以通过访问链接看到它们。

对于插件,我对MvcTurbine有很好的经验(它可以用于其他项目,不仅仅是mvc)。 如果您将它与Ninject结合使用并定义插件接口,即:

 IPlugin{ string Name {get;} someResultType PerformAction(someArgType arg); } 

并且,在你的插件dll中你通过从MvcTurbine实现IServiceRegistrator接口来注册IPlugin的实现,然后如果你在bin目录中放置dll插件,你的插件实现将被添加到传递到使用DI和接收的某个类的构造函数的列表中列表,或者您可以手动从IOC容器中解析它。 它比手工加载程序集并检查它们的接口/实现等要清晰得多……

如果您对此感兴趣,请询问是否有任何不清楚的地方,我会详细说明。

您可以使用内置的AssemblyMetadataAttribute类 ; 它从.NET 4.5开始提供。