2

Asp .net core MVC automatically detects controllers in the project at startup. I've been looking for a way to prevent this for certain Controllers. As a result, I figured out that I could implement IControllerFactory to filter out controllers dynamically. However, as I understand, it is for Controller creation, not detection. Is there any other way I could do this without implementing either IControllerFactory or the IControllerActivator? Is there any other component which involves in controller detection at the startup?

IControllerActivator is used by IControllerFactory for the controller creation.

3
  • _ looking for a way to prevent this for certain Controllers_ why you want prevent some controllers to be registered? Commented Jun 22, 2019 at 22:11
  • There are some components in my app. I want to disable them without excluding them from the project or modifying their access specifier. So, I thought best way to do it is to stop some controllers from being registered. Commented Jun 23, 2019 at 0:07
  • 1
    You can do it by creating and registering "NotInUse" Action Filter. Where you can check for controller name and return 404 if restricted controller were requested. Then you simply mark controllers with NotInUse attribute and remove it when you ready to use them. Commented Jun 23, 2019 at 0:18

2 Answers 2

1

You need to implement your own IControllerActivator and add your logic into there.

I'd suggest adding an attribute to the Controller, and the using reflection in the Create method to enable/disable the controller

public class CustomControllerResolver : IControllerActivator
{
    public object Create(ControllerContext actionContext)
    {
        var actionDescriptor = actionContext.ActionDescriptor;
        var controllerType = actionDescriptor.ControllerTypeInfo.AsType();
        return actionContext.HttpContext.RequestServices.GetRequiredService(controllerType);
    }

    public virtual void Release(ControllerContext context, object controller)
    {
    }
}

Register your custom resolver in the ServicesCollection

services.Replace(ServiceDescriptor.Transient<IControllerActivator, CustomControllerResolver>());
Sign up to request clarification or add additional context in comments.

Comments

1

I found a way to keep some Controllers from being registered. We can register a new convention that searches for controllers need to be removed and pop them from the controllers' list.

public class ApplicationDescription : IApplicationModelConvention
{

    public ApplicationDescription()
    {                      
    }

    public void Apply(ApplicationModel application)
    {
        var ctr = application.Controllers.Where((model) => {
            return model.ControllerType.IsEquivalentTo(typeof(IgnoredController));
        });
        if (ctr.Count() > 0)
        {
            foreach (var controller in ctr.ToList())
            {
                application.Controllers.Remove(controller);
            }
        }            
    }
}

Register the new convention with MVC

public class Startup
    {
        public void ConfigureServices(IServiceCollection services)
        {



            services.AddMvc((options)=> {

                options.Conventions.Add(new ApplicationDescription());
                options.Conventions.Add(new ControllerDescriptionAttribute("aa"));

            }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);
        }

        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        { 
        }
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.