2015-05-29 52 views
0

我有一个接口和两个类实现此接口。在这种情况下,我无法使用MEF概念。我的代码如下。请帮助我使用MEF转换相同的内容。托管可扩展框架 - 当两个类实现一个接口时无法使用mef

public interface IResultsRepository 
    { 
     IList<string> GetResults(); 
     string GetSummary(); 
    } 

[Export(typeof(IResultsRepository))] 
public class ExcelResultsRepository : IResultsRepository 
{ 
    private readonly string filePath; 
    private readonly string worksheetName; 
    [ImportingConstructor] 
    public ExcelResultsRepository([Import("FilePath")]string filePath, [Import("WorkSheetName")]string worksheetName) 
    { 
     this.filePath = filePath; 
     this.worksheetName = worksheetName; 
    } 
    public IList<string> GetResults() 
    { 
    } 
    public string GetSummary() 
    { 
    } 
} 

[Export(typeof(IResultsRepository))] 
public class ResultsFormRepository : IResultsRepository 
{ 
    private readonly ResultForm resultForm; 
    [ImportingConstructor] 
    public ResultsFormRepository([Import("ResultFormInstance")]ResultForm resultForm) 
    { 
     this.resultForm = resultForm; 
    } 
    public IList<string> GetResults() 
    { 

    } 
    public string GetSummary() 
    { 
    } 
} 

[Export("ResultFormInstance")] 
public class ResultForm 
{ 
    public string Tables 
    { 
     get { return ""; } 
    } 

    public string Summary 
    { 
     get 
     { 
      return ""; 
     } 
    } 
} 

[Export] 
public class ResultsContentConverter 
{ 
    private readonly IResultsRepository resultRepository; 

    [ImportingConstructor] 
    public ResultsContentConverter([Import(typeof(IResultsRepository))]IResultsRepository resultRepository) 
    { 
     this.resultRepository = resultRepository; 
    } 

    public ResultContent GetResultContent() 
    { 
     //logic to convert the format and return formatted object containg results and summary 
    } 
} 

[TestFixture] 
[Export] 
public class ResultComapreTest 
{ 
    [Import] 
    private ResultsContentConverter excelContentConverter; 

    [Import("ResultFormConverter", typeof(IResultsRepository))] 
    private ResultsContentConverter resultFormContentConverter; 

    [Test] 
    public void CompareResultFromResultForm() 
    { 
     ResultContent expectedResult; 
     ResultContent actualResult; 

     using (IResultsRepository excelResultsRepository = new ExcelResultsRepository(@"C:\Users\akuma211\Abhineet\Project\Sample\UnityContainerLearning\Sample\book1.xlsx", "sheet1")) 
     { 
      var converter = new ResultsContentConverter(excelResultsRepository); 

      expectedResult = converter.GetResultContent(); 
     } 

     using (IResultsRepository resultsRepository = new ResultsFormRepository(new ResultForm())) 
     { 
      var converter = new ResultsContentConverter(resultsRepository); 

      actualResult = converter.GetResultContent(); 
     } 

     Assert.AreEqual(expectedResult.Summary, actualResult.Summary); 
     Assert.AreEqual(expectedResult.Tables[0].Rows.Count, actualResult.Tables[0].Rows.Count); 
    } 
} 

在测试方法中,我应该使用MEF。请帮我

感谢

嗨,我在下面的编辑,因为我想的测试方法。

[Test] 
     public void CompareResultFromResultForm() 
     { 
      ResultContent expectedResult; 
      ResultContent actualResult; 

      Compose();// MEF composer, that composes my ResultsContentConverter object 
      //using (IResultsRepository excelResultsRepository = new ExcelResultsRepository(@"C:\Users\akuma211\Abhineet\Project\Sample\UnityContainerLearning\Sample\book1.xlsx", "sheet1")) 
      //{ 
      // var converter = new ResultsContentConverter(excelResultsRepository); 

      // expectedResult = converter.GetResultContent(); 
      //} 
      expectedResult = excelContentConverter.GetResultContent(); 

      //using (IResultsRepository resultsRepository = new ResultsFormRepository(new ResultForm())) 
      //{ 
      // var converter = new ResultsContentConverter(resultsRepository); 

      // actualResult = converter.GetResultContent(); 
      //} 
      actualResult = resultFormContentConverter.GetResultContent(); 

      Assert.AreEqual(expectedResult.Summary, actualResult.Summary); 
      Assert.AreEqual(expectedResult.Tables[0].Rows.Count, actualResult.Tables[0].Rows.Count); 
     } 

HI我用importmany,这样做,如下

ResultContent expectedResult; 
      ResultContent actualResult; 

      var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly()); 
      var container = new CompositionContainer(catalog); 
      container.ComposeExportedValue<string>("FilePath", @"C:\Users\akuma211\Abhineet\Project\Sample\UnityContainerLearning\Sample\book1.xlsx"); 
      container.ComposeExportedValue<string>("WorkSheetName", "sheet1"); 
      container.ComposeExportedValue<ResultForm>("ResultFormInstance", new ResultForm()); 

      container.ComposeParts(this); 
      //ResultComapreTest obj = container.GetExportedValue<ResultComapreTest>(); 

      foreach (IResultsRepository rep in repository) 
      { 
       var converter = new ResultsContentConverter(rep); 
       converter.GetResultContent(); 
      } 

但我不希望创建运用新的ResultsContentConverter对象。 相反的foreach我用

using (IResultsRepository excelResultsRepository = (repository.Where(rep => rep.GetType() == typeof(ExcelResultsRepository)).Select(rep => rep).First())) 
      { 
       var converter = new ResultsContentConverter(excelResultsRepository); 

       expectedResult = converter.GetResultContent(); 
      } 

      using (IResultsRepository resultsRepository = (repository.Where(rep => rep.GetType() == typeof(ResultsFormRepository)).Select(rep => rep).First())) 
      { 
       var converter = new ResultsContentConverter(resultsRepository); 

       actualResult = converter.GetResultContent(); 
      } 

      Assert.AreEqual(expectedResult.Summary, actualResult.Summary); 
      Assert.AreEqual(expectedResult.Tables[0].Rows.Count, actualResult.Tables[0].Rows.Count); 
+0

你到底在问什么?你能解释一下你的问题究竟是什么?你有错误吗?编译时或运行时?什么错误信息?你的断言失败了吗? – nvoigt

+0

我想让我的resultcontentconverter对象使用mef –

+0

创建好吧,那就是你想要的。你尝试了什么?发生了什么?你预期会发生什么? – nvoigt

回答

0

当然MEF给你一个组成异常。 您正在给框架提供两个相同接口的实现。 MEF如何能够检测到你想要的那个实现?

你可以解决这个问题并使用[ImportMany],它将基本上导入IResultsRepository接口的所有可用实现。

你会得到一个可用的实现列表,你可以循环找到你想要单元测试的实现。

欲了解更多信息,请参阅本网页: https://msdn.microsoft.com/de-de/library/dd460648(v=vs.110).aspx

https://msdn.microsoft.com/en-us/library/system.componentmodel.composition.importmanyattribute(v=vs.110).aspx

http://dotnetbyexample.blogspot.de/2010/04/very-basic-mef-sample-using-importmany.html

一个简单的例子: 有你的界面:

public interface IResultsRepository 
{ 
    IList<string> GetResults(); 
    string GetSummary(); 
} 

和两个类实现这个界面:

[Export(typeof(IResultsRepository))] 
class CustomResultContainer : IResultsRepository 
{ 
    [ImportingConstructor] 
    public CustomResultContainer(IDoNothing nothing) 
    { 
    } 

    public IList<string> GetResults() 
    { 
     throw new NotImplementedException(); 
    } 

    public string GetSummary() 
    { 
     throw new NotImplementedException(); 
    } 
} 

[Export(typeof(IResultsRepository))] 
class ResultContainerWithLogging : IResultsRepository 
{ 
    [ImportingConstructor] 
    public ResultContainerWithLogging(ILogger logger) 
    { 

    } 

    public IList<string> GetResults() 
    { 
     throw new NotImplementedException(); 
    } 

    public string GetSummary() 
    { 
     throw new NotImplementedException(); 
    } 
} 

请注意,构造函数互不相同,每个类都依赖于不同的接口(代表您的用例)。 Bot界面被mef注入。你可以找到这个部分在这里:

[Export(typeof(ILogger))] 
class VoidLogger : ILogger 
{ 
    public void Log() 
    { 
     Console.Write("Void Logging"); 
    } 
} 

[Export(typeof(IDoNothing))] 
class DoNothingStub : IDoNothing 
{ 
    public void doNothing() 
    { 

    } 
} 

interface ILogger 
{ 
    void Log(); 
} 

interface IDoNothing 
{ 
    void doNothing(); 
} 

现在组成了这一切在一起:

 private void startup() 
    { 
     var catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly().Location); 
     var container = new CompositionContainer(catalog); 
     container.ComposeParts(this); 

     foreach (var resultsRepository in this.repositories) 
     { 
      Debugger.Break(); 
     } 
    } 

    [ImportMany] 
    public List<IResultsRepository> repositories { get; set; } 
} 

这会给我irepositories的名单exactl两个元素,因为MEF发现两种实现方式,并将其注射给我。

+0

我正在尝试相同的。但是这两个类都有一个导入构造函数,它对于两个实现者类的存储库--ResultsFormRepository和ExcelResultsRepository具有不同的参数。我尝试使用私有IEnumerable 存储库;但我怎么用参数来组合这个。 –

+0

我没有看到importmany的任何示例,其中有不同数据类型的构造函数参数 –

+0

添加了一个示例。 – Xeun

相关问题