问题描述
|
我正在构建一个可扩展的应用程序,它将在运行时通过runtime0ѭ加载其他程序集。这些附加程序集将包含WPF资源字典(皮肤等),纯资源(Resx)和/或插件类。程序集也可以不包含公共类,而只能包含资源或资源字典。
我正在寻找一种识别程序集的方法,例如友好名称(例如\“ Additional skins \”或\“ Integrated browser \”),程序集的功能类型(SkinsLibrary,SkinsLibrary | PluginLibrary等)和其他信息(如ConflictsWith(new [] {\“ SkinsLibrary \”,\“ browserPlugin \”)。
到目前为止,我在程序集命名中使用约定(
*.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;
}
}
现在,您可以将这些属性添加到装配中。
以下两行可以添加到程序集中的任何位置,只要它们在名称空间之外即可。我通常将程序集属性放在Properties
文件夹中的AssemblyInfo.cs
文件中。
[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属性,您可以通过访问链接来查看。
, 您可以使用内置的AssemblyMetadataAttribute
类;从.NET 4.5开始可用。
, 对于插件,我在MvcTurbine方面有丰富的经验(它可以与其他项目一起使用,不仅可以用于mvc)。如果与Ninject结合使用并为插件定义接口,即:
IPlugin{
string Name {get;}
someResultType PerformAction(someArgType arg);
}
并且,在插件dll中,您可以通过从MvcTurbine实现IServiceRegistrator接口来注册IPlugin的实现,然后,如果将带有插件的dll放在bin目录中,则您的插件实现将被添加到列表中,该列表传递到使用DI的某些类的构造函数中并接收列出,或者您可以手动从IOC容器中解决它。
这比手工加载组件并检查它们的接口/实现等要干净得多。
如果您对此感兴趣,请询问是否有不清楚的地方,我会详细说明。