1

私はオープンエンドのアプリケーションを開発しており、MEFは初めてです。MEFを派生クラスから完全に隠す必要があります。これが私のシーンです。

BaseAssemblyがあります

public class ListContainer
{
    [ImportMany(typeof(IBase))]
    public List<IBase> MyObjects { get; set; }

    public void AssembleDriverComponents()
{
     .... Some code to create catalogue..
     //Crete the composition container
        var container = new CompositionContainer(aggregateCatalog);

        // Composable parts are created here i.e. the Import and Export components assembles here
        container.ComposeParts(this);
}
}

 [InheritedExport(typeof(IBase))]
public abstract class Base : IBase
{
    private IInfoBase infoBase;

    //This is something which I want to do. If I have a derived class from Base. 
      Then It does not need to use ImportingConstructor.
    [ImportingConstructor()]
    public Base(InfoBase nfoBase)
    {
        this.infoBase = infoBase;
    }
}

[InheritedExport(typeof(IInfoBase))]
public interface IInfoBase
{
    string Category { get; set; }
}


public class InfoBase : IInfoBase
{

    public string Category
    {
        get;
        set;
    }
}

他のアセンブリは、ベースアセンブリを指します。

ReferenceAssemblyには

public class Derived : Base
{
    public Derived(BaseInfo info)
        : base(info)
    {
        info.Category = "CategoryA";
    }
}

この場合、MEFは派生オブジェクトのオブジェクトを作成していません。

要約すると、ImportingConstructor用のExplicitExportのようなものも必要です。

4

1 に答える 1

2

MEF2を使用してこれを行うことができます。MEF2は、「属性付きプログラミングモデル」を置き換えたり補完したりできるコンベンションベースのプログラミングモデルを導入しています。

インターフェースの場合IBase

public interface IBase { }

抽象基本クラスBase

[InheritedExport(typeof(IBase))]
public abstract class Base : IBase
{
    private IInfoBase infoBase;

    //No ImportingConstructorAttribute. This will be set with conventions.
    public Base(IInfoBase infoBase)
    {
        this.infoBase = infoBase;
    }
}

いくつかのBase実装:

public class Derived : Base
{        
    public Derived(IInfoBase info)
        : base(info)
    {
        info.Category = "CategoryA";
    }
}

public class AnotherDerived : Base
{
    public AnotherDerived(IInfoBase info)
        : base(info)
    {
        info.Category = "CategoryB";
    }
}

情報インターフェースは変更されていません。

[InheritedExport(typeof(IInfoBase))]    
public interface IInfoBase
{
    string Category { get; set; }
}

エクスポートされたパーツがBaseの実装間で共有されないように、PartCreationPolicyAttributeを追加しました。しかし、これは問題ではありません。

[PartCreationPolicy(CreationPolicy.NonShared)]
public class InfoBase : IInfoBase
{
    public string Category
    {
        get;
        set;
    }
}

そして最後にListContainer

public class ListContainer
{
    [ImportMany(typeof(IBase))]
    public List<IBase> MyObjects { get; set; }

    public void AssembleDriverComponents()
    {
        var regBuilder = new RegistrationBuilder();
        //SelectConstructor is the equivalent of the ImportingConstructorAttribute.
        //Note that my approach here is very crude. Simply use the first constructor.
        regBuilder.ForTypesDerivedFrom<Base>().SelectConstructor(ctors => ctors.First());

        //Only an AssemblyCatalog for this example. Note that the registration 
        //builder is used here.
        var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly(), regBuilder);
        //Crete the composition container
        var container = new CompositionContainer(catalog);

        // Composable parts are created here i.e. the Import and Export components assembles here
        container.SatisfyImportsOnce(this);
        System.Diagnostics.Debug.Assert(this.MyObjects.Count == 2);
    }
}

MEFコンベンションの詳細: MEF2の記事シリーズMEF2でのコンベンションベースのパーツ登録の開始

于 2013-02-05T00:50:46.723 に答える