Problem attaching metadata to a specific export class

Nov 30, 2009 at 12:51 PM
Edited Dec 1, 2009 at 3:09 PM

Hello everyone,

I want to know if it is possible to have a metadata attribute class which can be attached to specific classes. In my example below, I have an ILocal interface and a LocalAttribute class. I want to know how I can constrain the LocalAttribute class to be attached to classes implementing ILocal interface only. When I attached the LocalAttribute to RemoteImp, I found that my Locals array contained 4 items (3 LocalImp and 1 RemoteImp). I don't know if it is a bug or if it is me who is not using MEF correctly.

Thanks in advance and MEF rocks,

Pascal.

 



public interface ILocal
{
bool ReadFile(string filePath);
}

public interface IRemote {}

[MetadataAttribute]
[AttributeUsage(AttributeTargets.Class, AllowMultiple=true)]
public class LocalAttribute : ExportAttribute
{
public LocalAttribute() : base(typeof(ILocal)) { }
public string Foo { get; set; }
}

public interface ILocalMetadata
{
IList<string> Foo { get; }
}

[Export(typeof(ILocal))]
[Local(Foo = "foo1")]
[Local(Foo = "foo2")]
public class LocalImp : ILocal
{
public bool ReadFile(string filePath)
{
return false;
}
}

[Export(typeof(IRemote))]
//How to warn others NOT to use LocaLAttribute here?
[Local(Foo = "foo3")]
public class RemoteImp : IRemote {}

public class Main
{
private CompositionContainer _container;

[ImportMany]
public Lazy<ILocal, ILocalMetadata>[] Locals { get; set; }

private void Test()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new AssemblyCatalog(Assembly.GetExecutingAssembly()));
_container = new CompositionContainer(catalog);

_container.ComposeParts(this);

//Locals has more elements than expected
foreach (var item in Locals)
{
//throws CompositionContractMismatchException when item.Value is RemoteImp
item.Value.ReadFile("toto.txt");
}
}

}