Locating Exports for Objects Created After ComposeParts Called

耗尽温柔 提交于 2019-12-21 18:41:06

问题


I've got a very simple app with a single export and multiple imports for the same type.

After I call ComposeParts I can see that the import worked in the same class where I called ComposeParts from - the MyService property has been hooked up.

The problem is that I have another UserControl that needs access to MyService and the property isn't set - it's in the same package etc. but it's not instatiated at the time I call ComposeParts.

If I make my CompositionContainer public / static and call ComposeParts and pass the UserControl the MyService property is set but that's a horrible solution.

Can anyone shed some light on what's going on? Is ComposeParts only smart enough to hook up existing objects or will an Import attribute be able to work on objects at a later time? Did I hook something up incorrectly?

public partial class App : Application    
{

  protected override void OnActivated(EventArgs e)
  {
    AssemblyCatalog assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());
    compositionContainer = new CompositionContainer(assemblyCatalog);
    compositionContainer.ComposeParts(this);
  }

  [Import(typeof(MyService))]
  public MyService MyService { get; set; }
}

Update:

I'm trying to upgrade a 250k line C# prject from the Service Provider Model found in .Net 2.0 to MEF.

It doesn't seem like you can have a new object instance automatically be hooked up to the services it requires solely through the Import attribute. It seems like you need to re-trigger the ComposeParts or something like that. Lame.

In the .Net 2.0 provider/container model you needed to explicitly add child objects to parent containers and finding a service would be a recursive check from children to parents containers. I'm not sure what the corrolary is in MEF??


回答1:


One thing that looks like an issue is that you have only one assembly in your catalog (the executing assembly). If this is a single-assembly project where all the [Export] items are in the same assembly, then it will work fine. If not, then you'll need to pass all the assemblies into the catalog or use a DirectoryCatalog.

You can mark the UserControl classes with [Export], then instead of calling their constructors, you can use CompositionContainer.GetExportedValue() to create the UserControl and fulfill all its [Import] needs in one go. However, this is not always feasible with UI's if the forms already have the controls on there at design-time. In this case, you'll have to call ComposeParts to setup the [Import] values.

It really boils down to how you are setting up the UserControl classes in the application. If you wire it up at runtime, then you have a chance to hook into the CompositionContainer to create the instances for you and wire them up automatically. If you are relying on design-time code to set up the controls, then you will need to replace all your GetService() calls with ComposeParts() calls.




回答2:


You can check out dI.Hook framework on Codeplex for dynamic hooks

Link: http://dihook.codeplex.com/



来源:https://stackoverflow.com/questions/5781328/locating-exports-for-objects-created-after-composeparts-called

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!