简体   繁体   中英

ASP.NET Core MVC main project can't reach Controllers in separate assembly

I want to use a separate project to store the Controllers for my test app. Due to how ASP.NET Core is working, you need to call services.AddMvc().AddApplicationPart with the assembly you want to add.

I use Visual Studio 2017 (so no more project.json there)

The problem is I can't reach the assembly I want to include!

I added reference there in my project:

在此输入图像描述

Also, I decided to use polyfill for AppDomian like so (to reach assembly I need):

 public class AppDomain
    {
        public static AppDomain CurrentDomain { get; private set; }

        static AppDomain()
        {
            CurrentDomain = new AppDomain();
        }

        public Assembly[] GetAssemblies()
        {
            var assemblies = new List<Assembly>();
            var dependencies = DependencyContext.Default.RuntimeLibraries;
            foreach (var library in dependencies)
            {
                if (IsCandidateCompilationLibrary(library))
                {
                    var assembly = Assembly.Load(new AssemblyName(library.Name));
                    assemblies.Add(assembly);
                }
            }
            return assemblies.ToArray();
        }

        private static bool IsCandidateCompilationLibrary(RuntimeLibrary compilationLibrary)
        {
            return compilationLibrary.Name == ("TrainDiary")
                || compilationLibrary.Dependencies.Any(d => d.Name.StartsWith("TrainDiary"));
        }
    }

But when I used it there wasonly one assembly in the list (only linked to this project itself, not one with Controllers).

Here is my Startup.cs :

public class Startup
    {

        public IConfigurationRoot Configuration { get; }
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                .AddEnvironmentVariables();

            Configuration = builder.Build();
        }
        // This method gets called by the runtime. Use this method to add services to the container.
        // For more information on how to configure your application, visit https://go.microsoft.com/fwlink/?LinkID=398940
        public void ConfigureServices(IServiceCollection services)
        {
            var assemblies = GetAssemblies(); // I tought I will find there Assmbly I need but no

            services.AddSingleton<IHttpContextAccessor, HttpContextAccessor>();
            services.AddReact();
            services.AddMvc();
            services.AddLogging();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseReact(config =>
            {
            });

            app.UseStaticFiles();
            app.UseMvcWithDefaultRoute();
        }

        public List<Assembly> GetAssemblies()
        {
            Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
            List<Assembly> currentAssemblies = new List<Assembly>();

            foreach (Assembly assembly in assemblies)
            {
                if (assembly.GetName().Name.Contains("TrainDiary"))
                {
                    currentAssemblies.Add(assembly);
                }
            }

            return currentAssemblies;
        }

    }

How can I get my project to also lookup controllers in the other project? Why couldn't it see it?

UPD

Tried to make directly like in this exapmle here.

So my code started looks like that:

var controllersAssembly = Assembly.Load(new AssemblyName("TrainDiary.Controllers")); 
services.AddMvc()
        .AddApplicationPart(controllersAssembly)
        .AddControllersAsServices();

And it succeed to get the assembly:

在此输入图像描述

But when I try to call Controller function - it fails!

Controller code:

[Route("Login")]
    public class LoginController: Controller
    {
        [Route("Login/Test")]
        public void Test(string name, string password)
        {
            string username = name;
            string pass = password;
        }
    }

Requests:

在此输入图像描述

UPD2 :

For some reason remove Routes helped:

public class LoginController: Controller
    {
        public void Test(string name, string password)
        {
            string username = name;
            string pass = password;
        }
    }

在此输入图像描述

So, if sum this up:

1) You need to Add Reference to your separate project with controllers.

2) Configure services (part):

public void ConfigureServices(IServiceCollection services)
{
  var controllersAssembly = Assembly.Load(newAssemblyName("SomeProject.MeetTheControllers"));

  services.AddMvc().AddApplicationPart(controllersAssembly).AddControllersAsServices();
}

3) My configure looks like that (pay attention to UseMvcWithDefaultRoute ):

   // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
        {
            loggerFactory.AddConsole();

            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseReact(config =>
            {
            });

            app.UseStaticFiles();
            app.UseMvcWithDefaultRoute();
        }

So in my case of controller like this you don't need to put Routes attribute here, just call it by Some/Test url

namespace SomeProject.MeetTheControllers.Test
{
    using Microsoft.AspNetCore.Mvc;

    public class SomeController: Controller
    {
        public void Test(string name, string notname)
        {
            string username = name;
            string nan = notname;
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM