.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开始提供。