Unlike a regular property, a metadata item is independent of the component itself.

This makes it useful when selecting one of many components based on runtime criteria; or, where the metadata isn’t intrinsic to the component implementation. Metadata could represent the time that an ITask should run, or the button caption for an ICommand.

Any publicly-readable properties on the attribute will become name/value attribute pairs - the name of the metadata will be the property name and the value will be the property value.

In the example below, the AgeMetadataAttribute will provide a name/value pair of metadata where the name will be Age (the property name) and the value will be whatever is specified in the attribute during construction.

Once you have a metadata attribute, you can apply it to your component types to provide metadata.

// Don't apply it to the interface (service type)publicinterfaceIArtwork{voidDisplay();}// Apply it to the implementation (component type)[AgeMetadata(100)]publicclassCenturyArtwork:IArtwork{publicvoidDisplay(){...}}

That component will require you to register a keyed service with the specified name. You’ll also need to register the component with the filter so the container knows to look for it.

varbuilder=newContainerBuilder();// Register the keyed service to consumebuilder.RegisterType<MyArtwork>().Keyed<IArtwork>("Painting");// Specify WithAttributeFiltering for the consumerbuilder.RegisterType<ArtDisplay>().As<IDisplay>().WithAttributeFiltering();// ...varcontainer=builder.Build();

That component will require you to register a service with the specified metadata name/value pair. You could use the attributed metadata class seen in earlier examples, or manually specify metadata during registration time. You’ll also need to register the component with the filter so the container knows to look for it.

varbuilder=newContainerBuilder();// Register the service to consume with metadata.// Since we're using attributed metadata, we also// need to register the AttributedMetadataModule// so the metadata attributes get read.builder.RegisterModule<AttributedMetadataModule>();builder.RegisterType<CenturyArtwork>().As<IArtwork>();// Specify WithAttributeFilter for the consumerbuilder.RegisterType<ArtDisplay>().As<IDisplay>().WithAttributeFiltering();// ...varcontainer=builder.Build();

The metadata attributes you create aren’t just used by default. In order to tell the container that you’re making use of metadata attributes, you need to register the AttributedMetadataModule into your container.

varbuilder=newContainerBuilder();// Register the service to consume with metadata.// Since we're using attributed metadata, we also// need to register the AttributedMetadataModule// so the metadata attributes get read.builder.RegisterModule<AttributedMetadataModule>();builder.RegisterType<CenturyArtwork>().As<IArtwork>();// ...varcontainer=builder.Build();

If you’re using metadata filters (KeyFilterAttribute or WithAttributeFiltering in your constructors), you need to register those components using the WithAttributeFiltering extension. Note that if you’re only using filters but not attributed metadata, you don’t actually need the AttributedMetadataModule. Metadata filters stand on their own.