Skip to content
This repository has been archived by the owner on Dec 14, 2018. It is now read-only.

Find ASP.NET Core 2 Razor Pages in another assembly #6934

Closed
xsoheilalizadeh opened this issue Oct 10, 2017 · 11 comments
Closed

Find ASP.NET Core 2 Razor Pages in another assembly #6934

xsoheilalizadeh opened this issue Oct 10, 2017 · 11 comments

Comments

@xsoheilalizadeh
Copy link

xsoheilalizadeh commented Oct 10, 2017

Hi, I want to locate My Project Razor Pages in another assembly.
for doing this I write following code:

        public void ConfigureServices(IServiceCollection services)
        {
            var adminAssembly = Assembly.Load(new AssemblyName("App"));
            services.AddMvc().AddApplicationPart(adminAssembly).AddRazorOptions(options =>
            {
                var previous = options.CompilationCallback;
                options.CompilationCallback = context =>
                {
                    previous?.Invoke(context);

                    context.Compilation = context.Compilation.AddReferences(
                        MetadataReference.CreateFromFile(typeof(dodo).Assembly.Location));
                };
            });

            services.Configure<RazorViewEngineOptions>(options =>
            {
                options.FileProviders.Add(new EmbeddedFileProvider(Assembly.Load("App")));
                options.FileProviders.Add(new PhysicalFileProvider(@"C:\Users\soheil\Documents\Visual Studio 2017\Projects\WebApplication5\App"));
            });
        }

my solution:
devenv_2017-10-10_18-44-26

when running localhost:5000/SameTodo Get Followig Error:

One or more compilation references are missing. Ensure that your project is referencing 'Microsoft.NET.Sdk.Web' and the 'PreserveCompilationContext' property is not set to false.

stack:

The type or namespace name 'SameTodoModel' could not be found (are you missing a using directive or an assembly reference?)
+
        public global::Microsoft.AspNetCore.Mvc.Rendering.IHtmlHelper<SameTodoModel> Html { get; private set; }
The type or namespace name 'SameTodoModel' could not be found (are you missing a using directive or an assembly reference?)
+
        public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<SameTodoModel> ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<SameTodoModel>)PageContext?.ViewData;
The type or namespace name 'SameTodoModel' could not be found (are you missing a using directive or an assembly reference?)
+
        public SameTodoModel Model => ViewData.Model;
The type or namespace name 'SameTodoModel' could not be found (are you missing a using directive or an assembly reference?)
+
        public global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<SameTodoModel> ViewData => (global::Microsoft.AspNetCore.Mvc.ViewFeatures.ViewDataDictionary<SameTodoModel>)PageContext?.ViewData;

and set PreserveCompilationContext to false but now worked how can I solve this problem?
also, ask this in StackOverflow

@pranavkm
Copy link
Contributor

Where's the type SameTodoModel located? It doesn't look very clear if it's part of 'App'.

@xsoheilalizadeh
Copy link
Author

xsoheilalizadeh commented Oct 10, 2017

located in App and Pages folder.

  • SameTodo.cshtml
    • SameTodo.cshtml.cs
      • SameTodoModel
        - OnGet()

@pranavkm
Copy link
Contributor

Does WebApplication5 reference App? I'm trying to figure out what you're doing to get it to load using Assembly.Load. In fact, if you could possibly share this as a single repo, that would certainly help.

@pranavkm
Copy link
Contributor

Some notes from my investigation:

I tried adding a compile reference \ runtime reference to an assembly not referenced by the application i.e. wire up things so you could point to an arbitrary project on disk + associated views.

I started with Assembly.LoadFile to add an AssemblyPart. If the assembly has a co-located deps.json:
(a) if it does have PreserveCompilationContext, resolving reference paths fail. DependencyModel does not look for binaries next to the deps file.
(b) If we do disable PreserveCompilationContext, DependencyModel finds the deps file but has any no CompileLibraries to work with. It ends up returning an empty sequence. Consequently the added AssemblyPart does not in itself gets referenced during view compilation.

Setting GenerateDependencyFile seems to be the only good way to get it actually referenced.

Once you get past this, you start running in to issues where the load context in which we load and reflect over the generated \ compiled Razor type isn't the same as the load context of the AssemblyPart assembly. I tried using AppDomain.AssemblyResolve, but that didn't help either. The only way to get things working was to reference the second project at which point things just worked.

Speaking to @sebastienros, it looks like Orchard switched from attempting to load arbitrary assemblies to actual references. I'm not entirely sure if this scenario works E2E very well.

@pranavkm
Copy link
Contributor

@soheilalizade feel free to reopen once you have a sample repro.

@molaie
Copy link

molaie commented Jan 13, 2018

@pranavkm I have very same problem. i've created a repo on github
Test Repo url
Hope you can test and investigate on it.
some more description: i'm using StructureMap for the DI part. the problem is that when in Yooshina.Host project, i add a reference to Yooshina.Modules.Core, there is no problem, but if i remove the direct reference and load it using reflection and other things, it gives the error:
An error occurred during the compilation of a resource required to process this request. Please review the following specific error details and modify your source code appropriately.
then i added <PreserveCompilationContext>false</PreserveCompilationContext> to Yooshina.Host.csproj, but this time i get the second error as in screenshot.

image

@molaie
Copy link

molaie commented Jan 13, 2018

also created a gist for error:
https://gist.github.com/molaie/788cb0279498c7efbbb4b751241d8896

@rynowak rynowak reopened this Jan 13, 2018
@rynowak
Copy link
Member

rynowak commented Jan 13, 2018

Reopening this since we have some information

@acinep
Copy link

acinep commented Jan 24, 2018

I am hitting something similar when trying to self-host ASP.NET Core - with views/controllers in a separate assembly.

Full repro available here https://github.com/acinep/Repro/tree/master/Mvc_6934

@pranavkm
Copy link
Contributor

@acinep your repro works fine for me i.e. I can see it print "Hello from embedded view" I clone and run. Can you try doing a clean build?

@pranavkm
Copy link
Contributor

pranavkm commented Feb 8, 2018

@molaie you are copying deps files along with your module binaries to the output directory. Deps files are looked up next to an assembly, but assemblies listed by it for purposes such as compilation are always resolved (a) the application's bin directory (b) the shared runtime (c) the runtime store. Consequently having the deps file in the modules directory prevents these assemblies from being resolved. Removing the deps file solves this immediate issue, but you're still going to run in to issues where you would have to manually resolve the transitive dependency graph of module dependencies as compilation references. I really wouldn't recommend going down this road.

In general, instead of rolling your module system, we recommend something more robust like the one Orchard Core provides. Orchard Core modules allow you to build modules as NuGet packages that can be added to your application on the fly. And you can use them as a low level framework without adopting the entire Orchard CMS infrastructure. Check out https://github.com/OrchardCMS/OrchardCore.Samples to see what this looks like.

@acinep if you're still seeing issues, feel free to open a new issue. I'm closing this since there isn't any action item for us to do.

@pranavkm pranavkm closed this as completed Feb 8, 2018
@pranavkm pranavkm removed their assignment Feb 8, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

7 participants