Issue with export/import - circularity issue?

Dec 11, 2010 at 9:09 PM

Im haivng trouble with a property export not being discovered. There's a circularity here which I think may be the problem, or I'm overlooking something dumb.  Or I've forgotten how property exports work.

Class A is created via MEF. Nonshared (actually it's an MVC controller and it is created through an override of CreateController if that matters). Thisimpots an instance of another class (shared) and also has a property export that looks like the following

      [Import (AllowDefault=true)]
      private IMenuService menuService;

      [Export("MenuFilePath")]
      public string MenuFilePath()
      {
         if (Server == null)
         {  return "Fred";}
         return Server.MapPath("~/Content/MenuDesign.xml");
      }

Class B (the implementation of IMenuService) has an import for MenuFilePath. This is a convoluted way of accessing the http server to resolve the mapping. The menPath is null (not Fred, and no breakpoint in the property is hit). I added the allow recomposition attribute to check. Same behavior when it is missing.

      [Import("MenuFilePath", AllowDefault = true, AllowRecomposition=true)]
      private string menuPath;

I've already checked, the problem is not in multiple dlls producing two MenuFilePaths.

Anyone have any ideas? Grimy details below:

? container.Catalog.Parts.Count()
2
? container.Catalog.Parts.First()
{Budget.Controllers.HomeController}
    [System.ComponentModel.Composition.ReflectionModel.ReflectionComposablePartDefinition]: {Budget.Controllers.HomeController}
    ExportDefinitions: {System.ComponentModel.Composition.Primitives.ExportDefinition[2]}
    ImportDefinitions: {System.ComponentModel.Composition.Primitives.ImportDefinition[1]}
    Metadata: Count = 1
Two export and one import as expected, details below


? container.Catalog.Parts.Last()
{Acom.MenuServices.MenuService}
    [System.ComponentModel.Composition.ReflectionModel.ReflectionComposablePartDefinition]: {Acom.MenuServices.MenuService}
    ExportDefinitions: {System.ComponentModel.Composition.Primitives.ExportDefinition[1]}
    ImportDefinitions: {System.ComponentModel.Composition.Primitives.ImportDefinition[2]}
    Metadata: Count = 0
Two import adn one export as expected, details below


? container.Catalog.Parts.First().ExportDefinitions.Last()
{Budget.Controllers.HomeController.MenuFilePath (ContractName="MenuFilePath")}
    [System.ComponentModel.Composition.ReflectionModel.ReflectionMemberExportDefinition]: {Budget.Controllers.HomeController.MenuFilePath (ContractName="MenuFilePath")}
    ContractName: "MenuFilePath"
    Metadata: Count = 2
Contract as expected, metadata below


? container.Catalog.Parts.Last().ImportDefinitions.First()
{Acom.MenuServices.MenuService.menuPath (ContractName="MenuFilePath")}
    [System.ComponentModel.Composition.ReflectionModel.ReflectionMemberImportDefinition]: {Acom.MenuServices.MenuService.menuPath (ContractName="MenuFilePath")}
    Cardinality: ZeroOrOne
    Constraint: {exportDefinition => ((exportDefinition.ContractName == "MenuFilePath") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "System.String".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))}
    ContractName: "MenuFilePath"
    IsPrerequisite: false
    IsRecomposable: false
As expected, metadata on export confirmation on constraint below


? container.Catalog.Parts.First().ExportDefinitions.Last().Metadata
Count = 2
    [0]: {[ExportTypeIdentity, System.String()]}
    [1]: {[System.ComponentModel.Composition.CreationPolicy, NonShared]}
This all looks good to me.



 

Dec 13, 2010 at 5:43 PM

Looks from here you're exporting a delegate, not a property. Could you turn it into a property?

 

      [Export]
      public string MenuFilePath
      {
         get {
           if (Server == null)
           {  return "Fred";}
           return Server.MapPath("~/Content/MenuDesign.xml");
         }
      }
Dec 14, 2010 at 6:37 AM

Aaarrrggggghhhhhh!!!!!!!

Look at something long enough and there's a good chance you'll overlook the completely obvious.

Thank you!

I am suprised that my export definition did not tell me this. The TypeIdentity comes up as string, when it seems it should have come up as Func<string>. I wonder if there is a bug in the export definition reporting.