我有返回实现特定接口的对象的方法。取决于参数方法返回不同的对象。所有都实现了相同的接口,所以我可以在方法外的接口上使用相同的方法,如Execute()。 这个解决方案迫使我避免使用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 :(得分: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;
}
}