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

Bor*_* B. 5 .net c# assemblies

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

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

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

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

Pat*_*son 3

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

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

public enum AssemblyPluginType
{
    Skins,
    Browser
}
Run Code Online (Sandbox Code Playgroud)

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

[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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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

[assembly: AssemblyPluginAttribute(AssemblyPluginType.Browser)]
[assembly: AssemblyPluginConflictAttribute(AssemblyPluginType.Skins, AssemblyPluginType.Browser)]
Run Code Online (Sandbox Code Playgroud)

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

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;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)