我正在开发一个开放式应用程序,我是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不会为派生的对象创建对象。
总之,我还需要像InheritedExport这样的ImportingConstructor。
答案 0 :(得分:2)
您可以使用MEF2执行此操作。 MEF2引入了Convention-Based Programming Model,它可以取代或补充“归因编程模型”。
对于界面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";
}
}
info界面未更改:
[InheritedExport(typeof(IInfoBase))]
public interface IInfoBase
{
string Category { get; set; }
}
添加了PartCreationPolicyAttribute,以便在Base的实现之间不共享导出的部分。这无关紧要。
[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公约的更多信息: MEF 2 article series和Getting started with convention-based part registration in MEF 2