简体   繁体   English

具有开放通用类型的MEF

[英]MEF with open generic type

I have these interfaces 我有这些接口

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);
}

Based on these interfaces i created classes like 基于这些接口我创建了类

[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...
}

The question is how do i use MEF to fufill all the object that implement IImageSource into an observable collection ImageSources? 问题是如何使用MEF将实现IImageSource的所有对象填充到可观察的集合ImageSources中? or how to use MEF to get all the object that implement IImageFilter into an observable collection ImageFilters? 或者如何使用MEF将实现IImageFilter的所有对象都放入可观察的集合ImageFilters中?

I tried the below but not working. 我尝试了以下但没有工作。 BTW, i'm using MEF and MEF Contrib. 顺便说一下,我正在使用MEF和MEF Contrib。

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

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

The collection of the ImageFilters can be make up of ImageFilters的集合可以组成

IImageFilter<string, string>
IImageFilter<string, int>
IImageFilter<int, double>

and here's the code I get MEF to do the composition. 这是我得到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);
}

Any idea how to get this to work? 知道如何让这个工作吗?

Here are some samples 这是一些样本

These do not work 这些都行不通

Cardinality mistmatch results in TestModule being rejected. 基数错误导致TestModule被拒绝。

1. 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. 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()
    {
    }
}

This one works 这个有效

[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()
    {
    }
}

Why? 为什么? Well, int is assignable from object , so i can export IEnumerable<int> as IEnumerable<object> with no problem. 好吧, int可以 object赋值,所以我可以将IEnumerable<int>导出为IEnumerable<object>而没有任何问题。

However, if i exported an IEnumerable<double> and IEnumerable<object> instead , it will fail because double is not assignable to int . 然而,如果我导出一个IEnumerable<double>IEnumerable<object> 相反 ,它会失败,因为double不可分配到int

My recommendations: 我的建议:

  • Consider a non-generic base interface 考虑一个非通用的基本接口
  • Import your filters to a property of type IEnumerable but use a contract name string to for the exports and import definitions. 将过滤器导入IEnumerable类型的属性,但使用合同名称字符串来导出和导入定义。 eg [Export("IMAGE_FILTERS")] 例如[Export("IMAGE_FILTERS")]

The export and import type does not match. 导出和导入类型不匹配。 Try 尝试

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM