How to use a controller in another assembly in ASP.NET Core MVC 2.0?

前端 未结 5 1804
一整个雨季
一整个雨季 2020-12-01 06:16

For the sake of modularity, I have created some controllers in different assemblies. Each assembly represents a bounded context (a module, a sub-system, a division, etc.) of

相关标签:
5条回答
  • 2020-12-01 06:44

    There is nothing wrong with the above answers, I just use a 1 liners as I know the class that is included in the external assembly that I'd like to load.

    The bellow sample comes from the ASP-WAF firewall and is used to load reporting endpoints and dashboard web pages in an existing web application in .net Core 3.1.

    services.AddMvc(options =>
    {                
        options.Filters.Add<Walter.Web.FireWall.Filters.FireWallFilter>();
        options.Filters.Add<Walter.Web.FireWall.Filters.PrivacyPreferencesFilter>();
    }).AddApplicationPart(Assembly.GetAssembly(typeof(Walter.Web.FireWall.DefaultEndpoints.ReportingController)));
    

    so to answer your question, let's assume that the TeacherController is in namespace Contoso.School.UserService your implementation would be:

    services.AddMvc(options =>
    {                
       //any option    }).AddApplicationPart(Assembly.GetAssembly(typeof(Contoso.School.UserService.TeacherController )));
    

    or, if you do not have any options then just ignore them and use this:

    services.AddMvc()  .AddApplicationPart(Assembly.GetAssembly(typeof(Contoso.School.UserService.TeacherController)));
    

    If you are not sure about the class in the assembly then us intelisence in your code starting with the namespace and look for a type to use or open object browser in visual studio

    Let me know if you have any issues.

    0 讨论(0)
  • 2020-12-01 06:52

    Martin above has the answer, thanks. However it is not immediately obvious how you pass an assembly to Startup.ConfigureServices. How I achieved this was... in the code where I create and start the webHost I call IWebHostBuilder.ConfigureServices and give it something containing the assembly (in my case a custom interface called IOutputProcess)

                _webHost = CreateWebHostBuilder().ConfigureServices(e => e.AddSingleton(_outputProcess)).Build();
                _webHost.Start();
    

    then in my Startup.ConfigureServices I pull that instance back out of the IServiceCollection with...

        public void ConfigureServices(IServiceCollection services)
        {
            var sp = services.BuildServiceProvider();
            var outputProcess = sp.GetService<IOutputProcess>();
            services.AddMvc().AddApplicationPart(outputProcess.ControllerAssembly).AddControllersAsServices();
        }
    

    I doubt instantiating a service provider purely for this purpose is the cleanest way to do things, but it does work. (I'm open to better ideas)

    0 讨论(0)
  • 2020-12-01 06:56

    I'm trying to resolve the controllers while migrating legacy unit tests from .NET Framework to aspnet core 3.1, this is the only way I got it working:

    var startupAssembly = typeof(Startup).Assembly;
    
    var services = new ServiceCollection();
    
    // Add services
    ...
    
    // Add Controllers
    services
        .AddControllers()
        .AddApplicationPart(startupAssembly)
        .AddControllersAsServices();
    

    If I change the order of the three last lines it does not work.


    Avoid doing this for unit testing unless you really have to, i.e. for legacy reasons. If you are not working with legacy code you are probably looking for integration tests.

    0 讨论(0)
  • 2020-12-01 06:58

    For .NET Core 3.0 the API has been slightly changed and the easiest way to register controllers from external assembly in Startup.cs looks like:

    public void ConfigureServices(IServiceCollection services)
    {
        var assembly = typeof(**AnyTypeFromRequiredAssembly**).Assembly;
    
        services.AddControllers()
            .PartManager.ApplicationParts.Add(new AssemblyPart(assembly));
    }
    
    0 讨论(0)
  • 2020-12-01 07:01

    Inside the ConfigureServices method of the Startup class you have to call the following:

    services.AddMvc().AddApplicationPart(assembly).AddControllersAsServices();
    

    Where assembly is the instance Assembly representing Contoso.School.UserService.dll.

    You can load it either getting it from any included type or like this:

    var assembly = Assembly.Load("Contoso.School.UserService");
    
    0 讨论(0)
提交回复
热议问题