2011-09-26 73 views
0

我有一個簡單的asp mvc應用程序,它使用MEF,並且有一條路徑可以被管理員訪問以刷新目錄目錄並組成部分,但是有一件事我想找出如何做是在插件被加載/卸載時通知一些代碼。MEF - 通知何時加載/卸載插件

這種情況是,當插件被加載時,他們註冊他們需要的路線,但是當他們被卸載時,我需要他們卸載他們的路線,因爲後續刷新嘗試重新註冊路線和它的炸彈。

是否有任何事件可以從MEF對象中調用?

插件容器是一樣的東西:

[ImportMany(typeof(ISomePluginInterface))] 
IEnumerable<ISomePluginInterface> Plugins {get; private set;} 

每個ISomePluginInterface都有類似:

public interface ISomePluginInterface 
{ 
    public void PluginLoaded(); 
    public void PluginUnloaded(); 
} 

回答

0

這是在理論上這Stackoverflow questionthis was my answer相似。在你的情況下,你有類似的需求,你想在插件啓動時觸發一個事件,並在不再需要時進行清理。

使用相同的概念,你可以使用InterceptingCatalog註冊路線,但我不會讓它的接口定義的一個明確部分這樣做,相反,你需要看看你的組件是如何結合在一起的整體而言,例如,如果註冊路由的操作不會用於所有插件,那麼它們在接口定義中存在的目的是什麼。您可以將路由註冊分爲單獨的界面,即IRouteRegistrar,並使用截取策略在第一次使用插件時自動調用適當的註冊方法,例如,我可以將界面分解爲:

public interface IPlugin 
{ 
    void SomeOperation(); 
} 

public interface IRouteRegistrar : IDisposable 
{ 
    void RegisterRoutes(); 
} 

後一個接口完成註冊路由的工作,我們使用Dispose模式確保在完成後清理它。因此,A樣本插件可以像:

[Export(typeof(IPlugin))] 
public class MyPlugin : IPlugin, IRouteRegistrar 
{ 
    public void SomeOperation() { } 

    public void RegisterRoutes() 
    { 
    // Register routes here... 
    } 

    protected virtual Dispose(bool disposing) 
    { 
    if (disposing) 
    { 
     // Unregister routes here... 
    } 
    } 

    void IDisposable.Dispose() 
    { 
    Dispose(true); 
    } 
} 

我唯一的出口爲IPlugin,但我保證我的插件也實現了IRouteRegistrar。我們使用的方式,是一種策略:

public class RouteRegistrarStrategy : IExportedValueInteceptor 
{ 
    public object Intercept(object value) 
    { 
    var registrar = value as IRouteRegistrar; 
    if (registrar != null) 
     registrar.RegisterRoutes(); 

    return value; 
    } 
} 

現在,只有當插件支持該接口將註冊路線。這也使您能夠將路由註冊接口應用於其他可以以不同方式使用的插件。你獲得更多的靈活性。要使用策略代碼,您需要將MefContrib項目添加到您的應用程序,並做多一點線了:

var catalog = new DirectoryCatalog(".\bin"); 
var config = new InterceptionConfiguration().AddInterceptor(new RouteRegistrarStrategy()); 

var interceptingCatalog = new InterceptingCatalog(catalog, configuration); 
var container = new CompositionContainer(interceptingCatalog); 
+0

在我的實際應用中,它們都拆了,他們揭露的路由和綁定接口上主插件接口,因此掛鉤它們的應用程序知道會觸發這兩個接口。應該仍然以上述方式工作。感謝你的回答! – somemvcperson