2
[InheritedExport]
[LoginMetadata]
public interface ILogon
{
    bool Authenticate ( string UserName, string Password );
}

public interface ILoginMetadata
{
    string Name
    {
        get;
    }

    string Description
    {
        get;
    }
}

[MetadataAttribute]
[AttributeUsage( AttributeTargets.Class | AttributeTargets.Interface, AllowMultiple = false, Inherited = true )]
public class LoginMetadataAttribute : ExportAttribute, ILoginMetadata
{
    public LoginMetadataAttribute ( )
        : base( typeof( ILogon ) )
    {
    }

    #region ILoginMetadata Members

    public string Name
    {
        get;
        set;
    }

    public string Description
    {
        get;
        set;
    }

    #endregion
}

public class LogonPlugins
{
    [ImportMany( typeof( ILogon ) )]
    public List<Lazy<ILogon, ILoginMetadata>> Plugins
    {
        get;
        set;
    }
}

public static class Logon
{
    private static LogonPlugins _Plugins = null;
    private static AggregateCatalog _Catalog = null;
    private static CompositionContainer _Container = null;

    public static LogonPlugins Plugins
    {
        get
        {
            if ( _Plugins == null )
            {
                _Plugins = new LogonPlugins( );

                _Catalog = new AggregateCatalog( );
                _Catalog.Catalogs.Add( new AssemblyCatalog( Assembly.GetExecutingAssembly( ) ) );

                _Container = new CompositionContainer( _Catalog );
                _Container.ComposeParts( _Plugins );
            }

            return ( _Plugins );
        }
    }
}

このコードは、Lazy モデルを使用して ILogon 型の拡張オブジェクトをロードすることを意図していました。Lazy の方法により、オブジェクトは ILogon を継承する必要があり、 LoginMetadata属性も宣言されている必要があります。LoginMetadata を強制したくないので、継承可能であると宣言し、パラメーターなしでインターフェイスに追加しました。私の問題は、プラグイン クラスで属性を宣言すると、最終的なリストに同じプラグイン タイプの 2 つのエントリが含まれることです。1 つはインターフェイスで宣言され、継承される空の属性です。もう 1 つはプラグイン クラスで宣言された属性用です。

克服する方法はありますか?

ありがとうピーター

4

1 に答える 1

0

エクスポートの 1 つは、ILogin インターフェイスに適用された InheritedExport からのもので、2 つ目は、ExportAttribute でもある LoginMetadataAttribute 属性からのものです。InheritedExport を削除するか、LoginMetadataAttribute から ExportAttribute 基本型を削除する必要があります。

一般に、メタデータを使用している場合は、特定のエクスポートに固有である必要があるため、インターフェイスから InheritedExport を削除し、ILogin をエクスポートするユーザーが LoginMetadataAttribute を適用し、必要なメタデータも提供することを期待する必要があります。これがルートである場合は、名前を LoginExportAttribute に変更することをお勧めします。

于 2013-08-02T16:24:32.080 に答える