问题
I am writing an Addin Framework in C# and I'm wondering how I can make Addin's unloadable without requiring a restart of the application.
I heard of AppDomains but how do these work? Can an Addin add extendability classes and be called in the Main AppDomain by Interfaces and still be unloadable and call cleanup code resulting in those classes being removed without that Assembly being in the Main AppDomain?
Or are there other methods of achieving unloadable addins, but IIRC other then AppDomain's you cannot unload an Assembly.
I also want the addin engine to be compatible with Mono if possible, so any answers try to stay compatible with Mono, if you can.
回答1:
You might want to look at Mono.Addins. There are some good looking samples here, Here are some of the details:.
The following code is a basic example of an add-in host application. This application runs a set of commands which can be implemented by add-ins:
using System;
using Mono.Addins;
[assembly:AddinRoot ("HelloWorld", "1.0")]
class MainClass
{
public static void Main ()
{
AddinManager.Initialize ();
AddinManager.Registry.Update ();
foreach (ICommand cmd in AddinManager.GetExtensionObjects<ICommand> ())
cmd.Run ();
}
}
The extension point for the above example can be declared like this:
using Mono.Addins;
[TypeExtensionPoint]
public interface ICommand
{
void Run ();
}
An add-in extending the above extension point would look like this:
using System;
using Mono.Addins;
[assembly:Addin]
[assembly:AddinDependency ("HelloWorld", "1.0")]
[Extension]
public class HelloCommand: ICommand
{
public void Run ()
{
Console.WriteLine ("Hello World!");
}
}
回答2:
Dynamically Loading Plug-ins / Add-ins
You didn't explicitly ask how to dynamically load add-in or plug-ins, but you can see this question (and my answer) on StackOverflow.com on how to do so.
Unloading Plug-ins and Add-ins
There is only one way that I am aware of to unload dynamically loaded plug-ins and add-ins: by loading the add-in in a separate AppDomain
and unloading the AppDomain
. For more information see this article on MSDN.
Existing Add-in / Plug-in Frameworks
Why reinvent something that already exists? I know of two plug-in frameworks.
- Mono.Add-ins - As mentioned in Ian's answer.
- Managed Add-in Framework (MAF) - This is the
System.AddIn
namespace
Some people talk about the Managed Extensibility Framework (MEF) as a plug-in or add-in framework, which it isn't. For more information see this StackOverflow.com question and this StackOverflow.com question.
回答3:
There are two parts to "unloading" an add-in.
Unregister the addin so it is not "connected" to your program (it is not hooked up to any events, holding any resource locks, is not needed by or called by the main program at any time, and is not actively running any code).
Unload the assembly containing the addin code.
The first part is entirely in your control - if your addin subscribes to an event, then when you ask it to shut down it must unsubscribe. If your program creates buttons and menu items for the addin, then it must know about them and be able to remove them when the addin shuts down. etc.
It is up to you to decide whether the addin is responsible for this (in which case a rogue addin could take down the entire application if it doesn't clean up properly), or whether the addin framework must provide mechanisms for connecting to the main application so that it is able to clean up all the links between the app and addin automatically (i.e. run the addin in a safer "sandbox" where it is less able to adversely affect the stability of the application or other addins).
Once the addin is shut down it becomes totally dormant, and then it will be safe to unload it. (However, unless you want to be able to update the addin dll while the program is running, you may find you don't even need to unload the addin - simply disabling it may achieve your needs)
来源:https://stackoverflow.com/questions/9043676/writing-an-addin-or-plugin-framework-in-c-sharp