How to add an existing instance to the MEF directory?

I have an instance of an object, and I want to end with the MEF directory that contains this instance of the object, exported as a specific type of interface. How can i do this?

TypeCatalog does not work here because (a) it creates a new instance instead of the existing one, and (b) this requires the type to have the [Export] attribute. In my case, the instance comes from the MEF metadata system, so MEF creates the base type, and I cannot add attributes to it.

As far as I can tell, the usual advice is: if you have an existing instance, you should add it to the container (for example, via CompositionBatch ), and not to the directory. But when I add this instance, I also add all types of AssemblyCatalog types, all in the same operation. I also want to be able to remove all these types later. It makes more sense to me to collect everything in AggregateCatalog. That way, I can add both the assembly and the instance in one atomic operation, and I can delete them all the same way.

For instance:

// Bootstrapper code to initialize MEF: public void Configure() { _selectedGameCatalog = new AggregateCatalog(); var globalCatalog = new AggregateCatalog(_selectedGameCatalog); _container = new CompositionContainer(globalCatalog); // ... more MEF initialization ... } // Sometime later, I want to add more stuff to the MEF ecosystem: public void SelectGame(Lazy<Game, IGameMetadata> entry) { var newCatalog = new AggregateCatalog(); // Make the assembly available to import: newCatalog.Catalogs.Add(new AssemblyCatalog(entry.Value.GetType().Assembly)); // I also want the metadata to be available to import: IGameMetadata metadata = entry.Metadata; newCatalog.Catalogs.Add(MakeCatalogFromInstance<IGameMetadata>(metadata)); // Replace whatever game was selected before: _selectedGameCatalog.Catalogs.Clear(); _selectedGameCatalog.Catalogs.Add(newCatalog); } 

The part I donโ€™t know how to do is "MakeCatalogFromInstance". How to create a directory containing an existing instance (registered as a specific type)?

Or, alternatively, if Iโ€™m all wrong about this, is there a better way to connect the entire directory and an existing instance to MEF at the same time, with the ability to disconnect them again again and replace them with something else?

+4
source share
2 answers

I think it is best to add types to the directory and then add the instance to the container.

Catalogs contain definitions of parts. Part definitions are used to create parts. (The types for this are ComposablePartDefinition and ComposablePart .) So you could theoretically write your own directory and definition of the part, which always returned the part corresponding to the instance when CreatePart was called. But directories are not really intended to be used that way.

+1
source

For prosperity ...

MEF subdivides the responsibilities of what type information should be used (directory) from actual instances of the executable object (container). This is a logical decision for me, especially when you are setting up a more complex MEF environment in your application.

If you need the ability to "change" containers "on the fly," I suggest you try using hierarchical containers. The root directory / container is filled with static types, and any of the child containers can be filled with each specific set of meta types that you need for your game.

Hope this helps, Mark

+1
source

Source: https://habr.com/ru/post/1347470/


All Articles