Pluginの実装4

Pluginのロード・アンロード処理です。
ロードのキモになるのは次のGatewayクラスです。

class Gateway : MarshalByRefObject
{
    public IWidget CreateInstance(string location, string className)
    {
        Assembly assembly = Assembly.LoadFrom( location );
        return ( (IWidget)assembly.CreateInstance( className ) );
    }
}

メインのアプリケーションドメインからはWidget毎のアプリケーションドメインを作成し、Gatewayクラスのインスタンスを作成します。
GatewayクラスはMarshalByRefObjectなので、proxy経由でWidgetのアプリケーションドメインで実行されます。
PluginアセンブリのロードはWidget用アプリケーションドメインのみで行われるため、アプリケーションドメインをアンロードすることによりアセンブリのアンロードが可能となります。


以下、WidgetPluginのロード・アンロードに関する処理部です。

    private AppDomain domain = null;
    private Gateway gateway = null;
    
    public void Load()
    {
        if ( this.domain != null )
        {
            return;
        }
    
        try
        {
            this.domain = AppDomain.CreateDomain( "WidgetDomain_" + Name );
        }
        catch
        {
            AppDomain.Unload( this.domain );
            this.domain = null;
            return;
        }
    
        this.gateway = (Gateway)this.domain.CreateInstanceAndUnwrap( "UsaWidget.Plugin", "UsaWidget.Plugin.Gateway" );
    }
    
    public void Unoad()
    {
        if ( this.domain == null )
        {
            return;
        }
    
        this.gateway = null;
    
        AppDomain.Unload( this.domain );
    }
    
    public IWidget CreateWidget()
    {
        if ( this.gateway == null )
        {
            return( null );
        }
    
        IWidget widget = this.gateway.CreateInstance( this.location, this.className );
    
        return( widget );
    }

割といいかげんな実装ですが…(´・ω・`)


なお、IWidget実装クラスもproxy経由でアクセスできるように、MarshalByRefObjecとして実装します。