2011-09-26 4 views
0

MEF를 사용하는 간단한 asp mvc 응용 프로그램이 있으며 관리자가 액세스하여 디렉토리 카탈로그를 새로 고치고 부품을 작성하는 경로가 있습니다. 플러그인을로드/언로드 할 때 일부 코드에 알리는 것입니다.MEF - 플러그인이로드/언로드 될 때 알림

시나리오는 플러그인을로드 할 때 필요로하는 경로를 등록하지만 언로드 할 때 경로를 언로드해야하므로 이후 새로 고침을하면 경로가 다시 등록되고 폭탄이 터지기 때문에 필요합니다.

MEF 개체에서 연결할 수있는 이벤트가 있습니까?

플러그인 컨테이너는 뭔가 같은 :

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

답변

0

Stackoverflow questionthis was my answer이에 대한 이론과 유사하다 :

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

각 ISomePluginInterface 같은 것을 가지고있다. 귀하의 경우에는 비슷한 필요성이 있으며, 플러그인이 시작될 때 이벤트를 시작하고 더 이상 필요하지 않을 때 정리할 수 있습니다.

동일한 개념을 사용하면 InterceptingCatalog을 사용하여 경로를 등록 할 수 있지만 인터페이스 정의에 명시 적으로 포함시키지 않아도됩니다. 대신 인터페이스를 구성하는 요소가 예를 들어, 경로 등록을위한 작업이 모든 플러그인에 사용되지 않는다면, 인터페이스 정의에 기존 경로의 목적은 무엇입니까? 경로 등록을 별도의 인터페이스 인 IRouteRegistrar으로 분리하고 플러그인을 처음 사용할 때 적절한 등록 방법을 자동으로 호출하는 인터셉트 전략을 사용할 수 있습니다 (예 : 인터페이스를 탈옥 할 수 있음).

public interface IPlugin 
{ 
    void SomeOperation(); 
} 

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

후자의 인터페이스는 경로 등록 작업을 수행하며, 완료 후에는 Dispose 패턴을 사용하여 정리합니다. IPlugin

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

나는 단지 수출,하지만 난 내 플러그인도 IRouteRegistrar 구현 보장 : 따라서, 샘플 플러그인과 유사 할 수있다. 우리가 사용하는 방법은 다음과 같습니다 :

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

    return value; 
    } 
} 

이제 플러그인이 해당 인터페이스를 지원하는 경우에만 경로를 등록합니다. 또한 다른 방법으로 사용할 수있는 다른 플러그인에 경로 등록 인터페이스를 적용 할 수 있습니다. 당신은 좀 더 융통성을 얻습니다. 그들은 모두 밖으로 분할 내 실제 응용 프로그램에서

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

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

, 그들이에 라우팅 및 바인딩 인터페이스를 노출 : 코드에서이 전략을 사용하려면, 당신은 최대의 앱에 MefContrib 프로젝트를 추가하고, 좀 더 와이어를 할 필요가 기본 플러그인 인터페이스이므로 두 인터페이스를 시작하는 응용 프로그램에 연결하는 것이 좋습니다. 위에서 설명한대로 작동해야합니다. 답변 해주셔서 감사합니다! – somemvcperson