neilharvey / FileSignatures

A small library for detecting the type of a file based on header signature (also known as magic number).
MIT License
258 stars 40 forks source link

DetermineFileFormat returns null when FileFormatInspector registerd using `services.AddSingleton<IFileFormatInspector, FileFormatInspector>();` #19

Closed efaruk closed 5 years ago

efaruk commented 5 years ago

When I register IFileFormatInspector with manually created instance it works when I let ServiceProvider to create an instance from registration, DetermineFileFormat always returns null even for known file types.

neilharvey commented 5 years ago

This is happening because when ServiceProvider instantiates the class, it chooses the constructor which accepts IEnumerable<FileFormat> instead of the empty constructor. But because no concrete FileFormat classes have been registered then the list of known formats is empty and so it cannot determine the format of a stream.

Here are some ways you can resolve the issue:

  1. Pass in an instance calling the empty constructor:

    services.AddSingleton<IFileFormatInspector>(new FileFormatInspector());

    This will register all the formats in the FileSignatures assembly.

  2. Use FileFormatLocator to scan for the formats you are interested in, then pass that to the constructor of FileFormatInspector and register that instance:

    var recognised = FileFormatLocator.GetFormats().OfType<Image>();
    var inspector = new FileFormatInspector(recognised);
    services.AddSingleton<IFileFormatInspector>(inspector);

    In this example, all the types which derive from Image (jpg, tiff, bmp, etc.) will be registered. Anything else will be ignored.

  3. Register the Format implementations manually with ServiceCollection:

    services.AddSingleton<IFileFormatInspector>(new FileFormatInspector());
    services.AddSingleton<FileFormat, Jpeg>();
    services.AddSingleton<FileFormat, Gif>();
    services.AddSingleton<FileFormat, Tiff>();

    This will then inject the specific formats registered into the FileFormatInspector, and only those formats will be recognised.

There are other ways to achieve this, but hopefully this should give you some ideas of how the recognised formats can be registered depending on your requirements.

efaruk commented 5 years ago

Sure it is ok, as long as you know the reason, but IMHO you should put such comments on example code or a warning to your readme.md, please...