It is possible to get the file loader you need by using MEF
and attachnig Metadata
to the exported parts.
Create metadata interface and attribute.
public interface IFileTypeMetadata
{
string FileExtension { get; }
}
The interface can contain as many properties you need. For this particular problem, it contain only one property FileExtension
. It is important that the property has only getter
. MEF
is designed not to allow changing of metadata at runtime. Then create the attribute that holds the metadata:
public class FileTypeAttribute : Attribute, IFileTypeMetadata
{
public string FileExtension { get; set; }
}
The FileTypeAttribute
class implements IFileTypeMetadata
interface, and you can add a setter
to the FileExtension
property. It is needed for implementing the FileLoader
classes, and MEF
will not complain because we will access the metadata via the IFileTypeMetadata
interface which contain properties that have only getters
Create the interface that file loader classes implement and the file loader classes.
public interface IFileLoader
{
string LoadFile();
}
The interface contains only one method for the sake of simplicity. And here is example of two different dummy file loader classes:
[Export(typeof(IFileLoader))]
[FileType(FileExtension = ".jpg")]
public class JpgFileLoader : IFileLoader
{
public string LoadFile()
{
return "JPG";
}
}
[Export(typeof(IFileLoader))]
[FileType(FileExtension = ".png")]
public class PngFileLoader : IFileLoader
{
public string LoadFile()
{
return "PNG";
}
}
Both classes implement the IFileLoader
interface and are exported as IFileLoader
parts, but they have different metadata, via the FileType
attribute.
Create the composition container
var catalog = new DirectoryCatalog("path to directory where dll's are located");
var compositionContainer = new CompositionContainer(catalog);
compositionContainer.ComposeParts();
Access exported parts
var fileLoaders = compositionContainer.GetExports<IFileLoader, IFileTypeMetadata>();
var jpgFileLoader = fileLoaders.FirstOrDefault(x => x.Metadata.FileExtension == ".jpg");
if (jpgFileLoader != null)
Console.WriteLine(jpgFileLoader.Value.LoadFile()); //should print "JPG"
var pngFileLoader = fileLoaders.FirstOrDefault(x => x.Metadata.FileExtension == ".png");
if (pngFileLoader != null)
Console.WriteLine(pngFileLoader.Value.LoadFile()); //should print "PNG"