具有开放通用类型的MEF

时间:2013-12-04 08:55:57

标签: c# mef

我有这些接口

public interface IImageSource<T>
{
    // Properties
    T OutputFrame { get; set; }
    string Name { get; set; }
    Guid Guid { get; set; }

    // Events
    event EventHandler<DmEventArgs<T>> NewFrameOutput;

    // Methods
    bool Start();
    bool Stop();
    void Initialize();
}

public interface IImageFilter<TIn, TOut>
{
    // Properties
    TIn Input { get; set; }
    string Name { get; set; }
    Guid Guid { get; set; }

    TOut Process(TIn frame);
}

基于这些接口,我创建了像

这样的类
[Export(typeof(IImageSource<>))]
public class AForgeImageSource : IImageSource<Image<Bgr, byte>>
{
    // Implementation...
}

[Export(typeof(IImageFilter<,>))]
public class AnotherFilter1 : IImageFilter<Image<Bgr, byte>, Image<Bgr, byte>>
{
    // Implementation...
}

问题是如何使用MEF将实现IImageSource的所有对象填充到可观察集合ImageSources中?或如何使用MEF将实现IImageFilter的所有对象都放入可观察集合中ImageFilters ?

我尝试过以下但不能正常工作。顺便说一句,我正在使用MEF和MEF Contrib。

    [ImportMany]
    public ObservableCollection<IImageSource<object>> ImageSources
    {
        // Implementation...
    }

    [ImportMany(typeof(IImageFilter<object, object>))]
    public ObservableCollection<IImageFilter<object, object>> ImageFilters
    {
        // Implementation...
    }

ImageFilters的集合可以由

组成
IImageFilter<string, string>
IImageFilter<string, int>
IImageFilter<int, double>

这是代码我得到了MEF来进行合成。

public void LoadPluginList()
{
    var pluginsDirectoryPath = Environment.CurrentDirectory + "\\Plugins";
    //var aggregateCatalog = new AggregateCatalog();
    //var genericCatalog = new GenericCatalog();

    var catalog = new DirectoryCatalog(pluginsDirectoryPath);
    var container = new CompositionContainer(catalog);

    container.ComposeParts(this);
}

知道如何让它发挥作用吗?

2 个答案:

答案 0 :(得分:2)

以下是一些示例

这些不起作用

基数错误导致TestModule被拒绝。

1

[Export(typeof(IEnumerable<>))]
public class IntegerCollection: List<int>
{

}

[ModuleExport(typeof(TestModule))]
public class TestModule : Microsoft.Practices.Prism.Modularity.IModule
{
    [Import(typeof(IEnumerable<>))]
    public IEnumerable<int> Integers
    {
        get { return m_Integers; }
        set { m_Integers = value; }
    } private IEnumerable<int> m_Integers;


    public void Initialize()
    {
    }
}

2

[Export(typeof(IEnumerable<>))]
public class IntegerCollection: List<int>
{

}

[ModuleExport(typeof(TestModule))]
public class TestModule : Microsoft.Practices.Prism.Modularity.IModule
{
    [Import]
    public IEnumerable<int> Integers
    {
        get { return m_Integers; }
        set { m_Integers = value; }
    } private IEnumerable<int> m_Integers;


    public void Initialize()
    {
    }
}

这个有效

[Export(typeof(IEnumerable<object>))]
public class IntegerCollection: List<int>
{

}

[ModuleExport(typeof(TestModule))]
public class TestModule : Microsoft.Practices.Prism.Modularity.IModule
{
    [Import(typeof(IEnumerable<object>))]
    public IEnumerable<int> Integers
    {
        get { return m_Integers; }
        set { m_Integers = value; }
    } private IEnumerable<int> m_Integers;


    public void Initialize()
    {
    }
}

为什么呢?好吧,int可以从 object分配,因此我可以将IEnumerable<int>导出为IEnumerable<object>,毫无问题。

但是,如果我导出IEnumerable<double>IEnumerable<object> 而不是,则会失败,因为double无法分配给int

我的建议:

  • 考虑非通用基础接口
  • 将过滤器导入IEnumerable类型的属性,但使用合同名称字符串来导出和导入定义。例如[Export("IMAGE_FILTERS")]

答案 1 :(得分:0)

导出和导入类型不匹配。尝试

[Export(typeof(IImageFilter<object,object>))]
public class AnotherFilter1 : IImageFilter<Image<Bgr, byte>, Image<Bgr, byte>>
{
// Implementation...
}