This project has moved. For the latest updates, please go here.

Sharing, lifetime and ExportFactory<T>

Sharing and part lifetime in Microsoft.Composition are controlled using a concept called Sharing Boundaries. If a part is shared, exports from the same part instance may satisfy the imports of multiple other parts.

A part instance may need to be shared across the entire application or container, (commonly called a Singleton). Or, instances of the part may be created and shared locally between a group of part instances participating in a unit of work, for example responding to an HTTP request, processing a message from a queue, or displaying a particular page in a navigation-based app.

The diagram below shows how an UndoBuffer part might be shared on a per-page basis in a navigation-driven app:

SharingBoundaries.png

Sharing boundaries in Microsoft.Composition are given string names, here the name of the sharing boundary is “Page”.

Creating a sharing boundary

Sharing boundaries are created using ExportFactory<T>. The SharingBoundary attribute names the boundary that will be created by the factory.

PageController uses ExporFactory<Page> to create and control the bounded parts:

[Export]
public class PageController
{
    [Import, SharingBoundary("Page")]
    public ExportFactory<Page> PageFactory { get; set; }

Although here the contract type Page and the boundary name coincide, this does not have to be the case.

The ExportFactory<Page>.CreateExport() method returns an Export<Page> object with the Page value:

    void ShowPage()
    {
        var page = PageFactory.CreateExport();
        page.Value.Show();
    }

This example lets the page variable go out of scope enabling the sharing boundary and all of the parts in it to be garbage collected when possible. Alternatively, disposing the Export<Page> object would cause all of the parts in the sharing boundary that implement IDisposable to be disposed. In server apps that manage resources like transactions and connections, it is good practice to always explicitly dispose sharing boundaries.

Marking a part as shared

The UndoBuffer part is shared within the “Page” sharing boundary:

[Shared("Page")]
public class UndoBuffer { }

If a part is marked as Shared but does not specify a sharing boundary, it will be a globally shared singleton.

In the absence of an explicit sharing attribute, a part is non-shared.

Last edited Jun 22, 2012 at 5:49 PM by nblumhardt, version 4

Comments

smushty Feb 12, 2015 at 10:13 AM 
Limited or no documentation on Lifetime, though the heading includes Lifetime.