2015-10-07 83 views
0

我有方法返回实现特定接口的对象。取决于参数方法返回不同的对象。所有实现相同的接口,所以我可以在方法外部的接口上使用像Execute()一样的方法。 此解决方案迫使我避免使用MEF。我怎样才能同时使用这两种解决方案?从MEF导入构造函数并在不同的类中分离不同的策略?MEF中的设计模式策略

下面是一个例子代码:

[Export(typeof(ICrowdMessageProcessorFactory))] 
public class CrowdMessageProcessorFactory : ICrowdMessageProcessorFactory 
{ 
    private readonly IDefaultCrowdRequestAnalyzer _defaultProcessor; 

    [ImportingConstructor] 
    public CrowdMessageProcessorFactory(IDefaultCrowdRequestAnalyzer defaultProcessor) 
    { 
     _defaultProcessor = defaultProcessor; 
    } 

    public Metadata PayloadMetadata { get; private set; } 

    public ICrowdMessageProcessor Create(InsertCrowdsourcingEventRequest request, DateTime fireUtcDateTime) 
    { 
     if (request == null) 
     { 
      throw new ArgumentNullException(nameof(request)); 
     } 

     PayloadMetadata = Metadata.Create(request); 
     var marketRegion = PayloadMetadata?.GetMarketRegion(); 

     switch (marketRegion) 
     { 
      case MarketRegion.Uk: 
       return new UkCrowdMessageProcessor(); 
     } 

     return new DefaultCrowdMessageProcessorAdapter(request, fireUtcDateTime, _defaultProcessor); 
    } 
} 

这里是使用该方法

[ImportingConstructor] 
    public CrowdResponseAnalyzer(
     ICrowdMessageProcessorFactory processorFactory) 
    { 
      _processorFactory = processorFactory; 
    } 

    public void Execute(InsertCrowdsourcingEventRequest request, DateTime fireUtcDateTime) 
    { 
     Guard.ArgumentNotNull(request, "request"); 

     try 
     { 
      ICrowdMessageProcessor processor = _processorFactory.Create(request, fireUtcDateTime); 
      processor.Execute(); 
     } 
     //(...) 
    } 

的总结: 我喜欢在UkCrowdMessageProcessor不同的策略中分离到不同的类,这里和DefaultCrowdMessageProcessorAdapter。但在新的这种类(ICrowdMessageProcessor)我也需要使用ImportingConstructor。我该怎么做?

+0

您目前如何决定返回哪个对象?也许分享你的代码? – TomDoesCode

+0

我已添加样本 – Rayet

+0

请将您的解决方案移至答案中。这使得它更清晰并帮助其他可能会遇到同样问题的人。谢谢 –

回答

0

解决方案1: 使用CompositionContainer中和它方法GetExportedValue。 当它看起来:

public ICrowdMessageProcessor Create(InsertCrowdsourcingEventRequest request, DateTime fireUtcDateTime) 
    { 
     if (request == null) 
     { 
      throw new ArgumentNullException(nameof(request)); 
     } 

     PayloadMetadata = Metadata.Create(request); 

     var marketRegion = PayloadMetadata?.GetMarketRegion(); 
     switch (marketRegion) 
     { 
      case MarketRegion.Uk: 
       return _cc.GetExportedValue<UkCrowdMessageProcessor>(); 
     } 

     return PrepareDefaultCrowdMessageProcessor(request, fireUtcDateTime); 
    } 

    private ICrowdMessageProcessor PrepareDefaultCrowdMessageProcessor(InsertCrowdsourcingEventRequest request, DateTime fireUtcDateTime) 
    { 
     var processor = _cc.GetExportedValue<DefaultCrowdMessageProcessorAdapter>(); 
     processor.Initialize(request, fireUtcDateTime, _defaultProcessor); 
     return processor; 
    } 

解决方案2:使用的ServiceLocator的GetInstance

解决方案3:这一个是唯一一个权从设计的角度来看

[Export(typeof(ICrowdMessageProcessorFactory))] 
public class CrowdMessageProcessorFactory : ICrowdMessageProcessorFactory 
{ 

    private readonly IDefaultCrowdRequestAnalyzer _defaultProcessor; 

    private readonly UkCrowdMessageProcessor _ukCrowdMessageProcessor; 

    private readonly DefaultCrowdMessageProcessorAdapter _defaultCrowdMessageProcessor; 

    [ImportingConstructor] 
    public CrowdMessageProcessorFactory(
     IDefaultCrowdRequestAnalyzer defaultProcessor, 
     UkCrowdMessageProcessor ukCrowdMessageProcessor, 
     DefaultCrowdMessageProcessorAdapter defaultCrowdMessageProcessor) 
    { 
     _defaultProcessor = defaultProcessor; 
     _ukCrowdMessageProcessor = ukCrowdMessageProcessor; 
     _defaultCrowdMessageProcessor = defaultCrowdMessageProcessor; 
    } 

    public Metadata PayloadMetadata { get; private set; } 

    public ICrowdMessageProcessor Create(InsertCrowdsourcingEventRequest request, DateTime fireUtcDateTime) 
    { 
     if (request == null) 
     { 
      throw new ArgumentNullException(nameof(request)); 
     } 

     PayloadMetadata = Metadata.Create(request); 

     var marketRegion = PayloadMetadata?.GetMarketRegion(); 
     switch (marketRegion) 
     { 
      case MarketRegion.Uk: 
       return _ukCrowdMessageProcessor; 
     } 

     return PrepareDefaultCrowdMessageProcessor(request, fireUtcDateTime); 
    } 

    private ICrowdMessageProcessor PrepareDefaultCrowdMessageProcessor(InsertCrowdsourcingEventRequest request, DateTime fireUtcDateTime) 
    { 
     _defaultCrowdMessageProcessor.Initialize(request, fireUtcDateTime, _defaultProcessor); 
     return _defaultCrowdMessageProcessor; 
    } 
}