Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dotnet CORE 3.1 - accessing an embedded resource (file) in an associated project library

I have been following THIS little tutorial on embedded resources. Its by Derek Comartin and deals with the simple operation of adding an embedded resource into the the .csproj file.

Fine. did that as per his instructions however I get null in the resourceStream. There were a couple of gotcha's re not setting your resource to "embedded resource" in properties etc but I did all that.

Here are the resource properties:

enter image description here

My solution has quite a number of projects that make it up including a main project or startup project. The resource or JSON file I want to use as an embedded resource is in the Initialisation project which is a DotNet Core library project and IS NOT the start up project.

I followed the advice regarding finding the names etc using:

var resourceNames = assembly.GetManifestResourceNames();

This revealed it was not even available so as a result I got "null" for the resource stream.

Here is my code for accessing the embedded resource.

    public void CATALOGInitialiseSuburbs(CATALOGContext context)
    {
        var assembly = Assembly.GetEntryAssembly();

        var resourceNames = assembly.GetManifestResourceNames();

        var resourceStream = assembly.GetManifestResourceStream("EmbeddedResource.SUBURB.Initialisations.SuburbJSON.australianSuburbs.json");


        using (var reader = new StreamReader(resourceStream, Encoding.UTF8))
        {
            var list = reader.ReadToEndAsync();
        }
    }

Here is my csproj file for the project that has the embedded resource.

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <ApplicationIcon />
    <Win32Resource />
  </PropertyGroup>

  <ItemGroup>
    <None Remove="SUBURB.Initialisations\SuburbJSON\australianSuburbs2019-08.json" />
    <None Remove="SUBURB.Initialisations\SuburbJSON\australian_postcodes 2019.csv" />
  </ItemGroup>

  <ItemGroup>
    <EmbeddedResource Include="SUBURB.Initialisations\SuburbJSON\australianSuburbs2019-08.json" />
    <EmbeddedResource Include="SUBURB.Initialisations\SuburbJSON\australian_postcodes 2019.csv" />
  </ItemGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.0" />
  </ItemGroup>

  <ItemGroup>
    <ProjectReference Include="..\JobsLedger.AUTHORISATION\JobsLedger.AUTHORISATION.csproj" />
    <ProjectReference Include="..\JobsLedger.CATALOG.ENTITIES\JobsLedger.CATALOG.ENTITIES.csproj" />
    <ProjectReference Include="..\JobsLedger.CATALOG\JobsLedger.CATALOG.csproj" />
    <ProjectReference Include="..\JobsLedger.DATA\JobsLedger.DATA.csproj" />
  </ItemGroup>

</Project>

Here is my csproj file for the main project...

<Project Sdk="Microsoft.NET.Sdk.Web">

    <PropertyGroup>
        <TargetFramework>netcoreapp3.1</TargetFramework>
        <TypeScriptCompileBlocked>true</TypeScriptCompileBlocked>
        <TypeScriptToolsVersion>Latest</TypeScriptToolsVersion>
    </PropertyGroup>


    <ItemGroup>
        <PackageReference Include="FluentValidation" Version="8.6.1" />
        <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.0" />
        <PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="3.1.0" />
        <PackageReference Include="Microsoft.EntityFrameworkCore" Version="3.1.0" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Analyzers" Version="3.1.0" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="3.1.0" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="3.1.0" />
        <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="3.1.0">
          <PrivateAssets>all</PrivateAssets>
          <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
        </PackageReference>
        <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="5.6.0" />
        <PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="3.1.0" />
    </ItemGroup>


    <ItemGroup>
      <ProjectReference Include="..\JobsLedger.AUTHORISATION\JobsLedger.AUTHORISATION.csproj" />
      <ProjectReference Include="..\JobsLedger.CATALOG\JobsLedger.CATALOG.csproj" />
      <ProjectReference Include="..\JobsLedger.DATA\JobsLedger.DATA.csproj" />
      <ProjectReference Include="..\JobsLedger.INITIALISATION\JobsLedger.INITIALISATION.csproj" />
      <ProjectReference Include="..\JobsLedger.TESTDATA\JobsLedger.TESTDATA.csproj" />
    </ItemGroup>


    <Target Name="DebugRunWebpack" BeforeTargets="Build" Condition=" '$(Configuration)' == 'Debug' And !Exists('wwwroot\dist') ">
        <!-- Ensure Node.js is installed -->
        <Exec Command="node --version" ContinueOnError="true">
            <Output TaskParameter="ExitCode" PropertyName="ErrorCode" />
        </Exec>
        <Error Condition="'$(ErrorCode)' != '0'" Text="Node.js is required to build and run this project. To continue, please install Node.js from https://nodejs.org/, and then restart your command prompt or IDE." />

        <!-- In development, the dist files won't exist on the first run or when cloning to
                 a different machine, so rebuild them if not already present. -->
        <Message Importance="high" Text="Performing first-run Webpack build..." />
        <Exec Command="npm install" />
        <Exec Command="npm ddp" />
        <Exec Command="npm run webpack:Debug" />
    </Target>

    <Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish">
        <!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
        <Exec Command="npm install" />
        <Exec Command="npm ddp" />
        <Exec Command="npm run webpack:$(Configuration)" />

        <!-- Include the newly-built files in the publish output -->
        <ItemGroup>
            <!-- First, clean up previously generated content that may have been removed. -->
            <ContentWithTargetPath Remove="@(ContentWithTargetPath)" Condition="!Exists('%(Identity)')" />
            <_WebpackFiles Include="wwwroot\dist\**" />
            <ContentWithTargetPath Include="@(_WebpackFiles->'%(FullPath)')" RelativePath="%(_WebpackFiles.Identity)" TargetPath="%(_WebpackFiles.Identity)" CopyToPublishDirectory="Always" />
        </ItemGroup>
    </Target>

</Project>

I am pretty sure it would show up if it was in the main project but it isnt in that project.

How do I access an embedded resource that is an embedded resource in a sub project (dotnet core library)?

like image 683
si2030 Avatar asked Jan 02 '20 09:01

si2030


1 Answers

I found THIS QUESTION which indicated that I could use the assembly the class was in and then find the names of the resources in that class.

string[] resourceNames = this.GetType().Assembly.GetManifestResourceNames();
foreach(string resourceName in resourceNames)
{
    Console.WriteLine(resourceName);
}

Stepping at this point and looking at what it captured gave me firstly the knowledge I was accessing the assembly this class was in and more importantly it also listed the embeddedResource I had there.

So, This is what I did the access the resource.

    var resourceStream = this.GetType().Assembly.GetManifestResourceStream("JobsLedger.INITIALISATION.SUBURB.Initialisations.SuburbJSON.australianSuburbs.json");


    using (var reader = new StreamReader(resourceStream, Encoding.UTF8))
    {
        var list = reader.ReadToEndAsync();
    }

Note the first attempt gave me the full path the embedded resource was located at. I used that to create the location and correct assembly led me to the resource.

like image 85
si2030 Avatar answered Sep 23 '22 22:09

si2030