MEF导出需要远程数据(如DB数据)才能创建

时间:2014-06-20 14:05:22

标签: mef factory-pattern

请原谅开头的长篇说明。问题在最后。

我有一个Windows服务,应该从一些数据源读取数据(由IDataSource接口表示)。

我正在我的项目中使用MEF,我正在考虑通过ctor注入注入所需的数据源,如下所示:

[Export(typeof(Service))] 
public class Service:ServiceBase{
     [ImportingConstructor] 
     public Service([ImportMany]IEnumerable<IDataSource> dataSources){
         //...
     }
}

然而,这样做有一个问题。该服务需要使用任何数据源组合:相同类型的多个数据源(例如:2个CSVDataSource实例)或不同类型的多个数据源(例如:2个CSVDataSource实例和1个SQLDataSource实例)。

每个数据源都具有从数据库中检索的属性,以便正确设置它。这些设置可能指示从何处读取数据以及以何种间隔读取数据。这就是为什么在我的实现中,数据源有一个接受id的ctor。此ID用于标识数据库中的数据源,并从数据库中检索特定的数据源设置。这可以在下面看到。

public class CSVDataSource: IDataSource{
    public CSVDataSource(int dsId){
        //call web service in order to get properties to
        //properly set up the data source.
    }
    //...
}

我觉得上面提供的服务定义不适合这种情况。我能想到的另一种方法是使用某种允许服务在其中动态创建数据源的工厂。这个实现可能如下所示。

public class Service:ServiceBase{
        [ImportingConstructor]
        public Service(IDataSourceFactory dsFactory)
        {
            if (dsFactory == null) throw new ArgumentNullException("dsFactory");
            IEnumerable<IDataSource> dataSources = dsFactory.CreateAll();
        }
    }

[Export(typeof(IDataSourceFactory))]
    [PartCreationPolicy(CreationPolicy.Shared)]
    public class DataSourceFactory:IDataSourceFactory
    {
        private readonly int agentId;
        [ImportingConstructor]
        public DataSourceFactory([Import("AgentId")]int agentId)
        {
            this.agentId = agentId;
        }
        public IEnumerable<IDataSource> CreateAll()
        {
            List<IDataSource> dataSources = new List<IDataSource>();
            //access web service and instantiate the data sources
            return dataSources;
        }
    }

现在问我的问题:

  1. 我的工厂方法是一个好的想法还是我应该寻找另一种方法?

  2. 是否可以让导出需要来自远程位置的数据才能创建?

1 个答案:

答案 0 :(得分:0)

您以前遇到过ExportMetadataAttribute吗?它允许您将元数据分配给导出,您可以在创建导出之前查看该导出。您可以将IDataSources导入为Lazy,然后应该能够使用所需参数自行创建它们。

Lazy和ExportMetadata here

有很好的细分