Embedded resource in .Net Core libraries
UPDATE:
.NET Core 1.1 and later have dropped project.json
and returned to .csproj
files.
This changes Step 2, but not all that much. The necessary lines are very similar:
<ItemGroup>
<Content Remove="_fonts/OpenSans.ttf" />
<Content Remove="_fonts/OpenSans-Bold.ttf" />
<Content Remove="_fonts/OpenSans-Italic.ttf" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="_fonts/OpenSans.ttf" />
<EmbeddedResource Include="_fonts/OpenSans-Bold.ttf" />
<EmbeddedResource Include="_fonts/OpenSans-Italic.ttf" />
</ItemGroup>
There may be a similar *.tff
form; unconfirmed.
Steps 1 and 3 are unchanged.
To use embedded resources in .NET Core 1.0 project do the following:
-
Add your embedded file(s) as usual.
Example: some FONT files on a directory named "_fonts"
-
Modify "project.json" to include the related resources.
In my case:
"buildOptions": { "embed": { "include": [ "_fonts/*.ttf" ] } },
-
Access the embedded resource in code.
var assembly = typeof(MyLibrary.MyClass).GetTypeInfo().Assembly; Stream resource = assembly.GetManifestResourceStream("MyLibrary._fonts.OpenSans.ttf");
The key point is to use the right name on
GetManifestResourceStream
call. You have to use[assembly name].[directory].[file name]
.
Now that project.json
is deprecated, you have to specify this in the .csproj
file.
<ItemGroup>
<EmbeddedResource Include="_fonts\*.ttf" />
</ItemGroup>
You can use a wildcard as shown, or just list out the files explicitly.
With newer versions of .Net Core - 2.0 or greater - there's a specialized class EmbeddedFileProvider
that abstract the embedded file reading. To use it, add Microsoft.Extensions.FileProviders.Embedded
package to your application:
dotnet add package Microsoft.Extensions.FileProviders.Embedded
The EmbeddedFileProvider
allows you to create a stream reader, and use according to your scenario:
var embeddedProvider = new EmbeddedFileProvider(Assembly.GetExecutingAssembly());
using (var reader = embeddedProvider.GetFileInfo("yourfile.ext").CreateReadStream())
{
// some logic with stream reader
}
People have already generally answered this, so this is a rendering of the answers into something simple.
Before using the following, the file should be added as an embedded resource to the .csproj / project.json
Usage
var myJsonFile = ReadManifestData<Tests>("myJsonFile.json");
- Parameter: embedded filename name; Type: any class from the target resource's assembly
- looks for an embedded resource with that name
- returns the string value
Method
public static string ReadManifestData<TSource>(string embeddedFileName) where TSource : class
{
var assembly = typeof(TSource).GetTypeInfo().Assembly;
var resourceName = assembly.GetManifestResourceNames().First(s => s.EndsWith(embeddedFileName,StringComparison.CurrentCultureIgnoreCase));
using (var stream = assembly.GetManifestResourceStream(resourceName))
{
if (stream == null)
{
throw new InvalidOperationException("Could not load manifest resource stream.");
}
using (var reader = new StreamReader(stream))
{
return reader.ReadToEnd();
}
}
}
I have not confirmed this in documentation, but for me, it would appear the auto-generated Resource code that retrieves embedded files found in Resource.Designer.cs is now functioning again in .NET Core 3.1. I can now retrieve an embedded jpg simply by calling the Properties.Resources.MyImageName which returns a Bitmap object.