简体   繁体   中英

MEF ImportMany not working with Caliburn.Micro

Here is my metadata:

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class ModuleAttribute : ExportAttribute, IModuleMetadata
{
    public ModuleAttribute(string Contract) : base(Contract,typeof(IScreen))
    {            
        Region = Region.Sidebar;
        IsVisible = true;
        Order = short.MaxValue;
        Description = string.Empty;
    }

    public string Module { get; set; }        
    public Region Region { get; set; }        
    public string DisplayName { get; set; }        
    public bool IsVisible { get; set; }
    public string Description { get; set; }
    public short Order { get; set; }
}

My interface:

public interface IModuleMetadata
{       
   string Module { get; set; }
   Region Region { get; set; }
   string DisplayName { get; set; }
   bool IsVisible { get; set; }
   string Description { get; set; }
   short Order { get; set; }
}

I am accessing using:

[ImportMany]
public IEnumerable<Lazy<IScreen, IModuleMetadata>> Mods
{
    get;
    set;
}

But always my Mods end up being null .

Update:

[Module("Unit", Module = "Stock")]
class UnitViewModel : BaseViewModel, ICUDB, IHandle<UnitModel>
{

Interestingly, when I ask using GetExport. I am getting all the 15 exported classes.

var ex = container.GetExports<IScreen, JIMS.Common.Interface.IModuleMetadata>();

You need to check to make sure you are matching contracts which means digging into the metadata. While I recommend doing that so you can see how MEF puts all the pieces-parts together, you should try specifying the type for ImportMany .

Another thing to check is how BaseViewModel is created. If you did a new BaseViewModel() from the shell or other location, MEF won't work its magic inside the class. MEF needs to create any object that will be using MEF.

Since you are using a contract for the export you will need the same contract for the import.

Like:

[ImportMany("Unit")]
public IEnumerable<Lazy<IScreen, IModuleMetadata>> Mods

Another way to make this work is to modify the export to:

[Module(null, Module = "Stock")]
class UnitViewModel : BaseViewModel, ICUDB, IHandle<UnitModel>

By passing null or the empty string as a contract then the type will be used.

If you don't always need a contract then you can add a parameterless .ctor to ModuleAttribute .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM