.Net 4 - Include custom information in assembly

試著忘記壹切 提交于 2019-12-10 15:09:23

问题


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.

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").

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.


回答1:


EDIT: I've updated the answer with some more detailed information.

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.

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)]

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



回答2:


I am partially getting information but

you can add Custom AssemblyInfo Attributes which you can see by visiting link..




回答3:


You can use the built-in AssemblyMetadataAttribute class; it is available since .NET 4.5.




回答4:


For plugins, I have great experience with MvcTurbine (it can be used with other projects, not only mvc). If you use it in combination with Ninject and define interface for plugin, ie:

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

}

and, in your plugin dll you register implementation of IPlugin by implementing IServiceRegistrator interface from MvcTurbine, then if you place dll with plugin in bin directory, your plugin implementation will be added to list that is passed into constructor of some class that uses DI and receives List, or you can resolve it from IOC container by hand. It is a lot cleaner than loading your assemblies by hand and inspecting them for interfaces/implementations etc...

If you are interested in this, please ask if anything is unclear and I will elaborate.



来源:https://stackoverflow.com/questions/6354852/net-4-include-custom-information-in-assembly

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!