As we all know, when we derive a class and use polymorphism, someone must know somewhere which class should implement it. We can use factories, a large switch statement, if-else-if, etc. I just learned from Bill K that this is called Injection Dependency.
My question is: is reflection and attributes good as a dependency injection mechanism? Thus, the list is populated dynamically as new types are added.
Here is an example . Please do not report how you can upload images in other ways, as we know.
Suppose we have the following ImageFileFormat interface:
public interface IImageFileFormat
{
string[] SupportedFormats { get; };
Image Load(string fileName);
void Save(Image image, string fileName);
}
Various classes implement this interface:
[FileFormat]
public class BmpFileFormat : IImageFileFormat { ... }
[FileFormat]
public class JpegFileFormat : IImageFileFormat { ... }
, Load()/Save() Extensions.
class ImageLoader
{
public Image Load(string fileName)
{
return FindFormat(fileName).Load(fileName);
}
public void Save(Image image, string fileName)
{
FindFormat(fileName).Save(image, fileName);
}
IImageFileFormat FindFormat(string fileName)
{
string extension = Path.GetExtension(fileName);
return formats.First(f => f.SupportedExtensions.Contains(extension));
}
private List<IImageFileFormat> formats;
}
, , () .
:
public ImageLoader()
{
formats = new List<IImageFileFormat>();
formats.Add(new BmpFileFormat());
formats.Add(new JpegFileFormat());
}
:
public ImageLoader()
{
formats = new List<IImageFileFormat>();
foreach(Type type in Assembly.GetExecutingAssembly().GetTypes())
{
if(type.GetCustomAttributes(typeof(FileFormatAttribute), false).Length > 0)
{
formats.Add(Activator.CreateInstance(type))
}
}
}
, , . , , , , , , , .
, .