Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

ASP.NET 5: Using POCO controllers

DZone's Guide to

ASP.NET 5: Using POCO controllers

·
Free Resource

ASP.NET 5 supports POCO controllers. Yes, controller classes that doesn’t extend Controller base class. These controllers look a little bit different by some small aspects and sometimes we may need to help framework detect our POCO controllers. This posting gives you complete overview of POCO controllers in next ASP.NET.

Simple POCO controller

First let’s define simple controller that doesn’t inherit from Controller base class.

public class PocoController

{

    public IActionResult Index()

    {

        return new ContentResult() { Content = “Hello from POCO controller!” };

    }

}

To make this controller work with views we need some additional code.

public class PocoController

{

    private readonly IModelMetadataProvider _metadataProvider;

 

    public PocoController(IModelMetadataProvider metadataProvider)

    {

        _metadataProvider = metadataProvider;

    }

 

    public IActionResult Index()

    {

        var viewData = new ViewDataDictionary<string>(_metadataProvider);

        viewData.Model = “Hello from POCO controller!”;

 

        return new ViewResult() { ViewData = viewData };

    }

}

Now we have basic primitive POCO controller that ASP.NET 5 will happily use.

Fooling ASP.NET

Now let’s do the little trick and call our controller just as Poco.

public class Poco

{

    // …

}

When trying to use controller now we run to problems.

ASP.NET 5: POCO controller not found

Why? Because ASP.NET cannot detect controller anymore.

How controller is detected by default?

When sniffing around in MVC source you can find the method that MVC uses to find out if given type is controller type of not. It is done in DefaultActionDiscoveryConventions class.

public virtual bool IsController([NotNull] TypeInfo typeInfo)

{

    if (!typeInfo.IsClass ||

        typeInfo.IsAbstract ||

        typeInfo.ContainsGenericParameters)

    {

        return false;

    }

 

    if (typeInfo.Name.Equals(“Controller”, StringComparison.OrdinalIgnoreCase))

    {

        return false;

    }

 

    return typeInfo.Name.EndsWith(“Controller”, StringComparison.OrdinalIgnoreCase) ||

           typeof(Controller).GetTypeInfo().IsAssignableFrom(typeInfo);

}

If we have POCO controller and we don’t name it as SomethingController then MVC is not considering our POCO controller as controller.

Using action discovery convention

If there are additional rules for detecting controllers we can use action discovery conventions to tell MVC if class is constructor or not. Here is simple discovery convention class that works with our POCO controller.

public class MyActionDiscoveryConventions : DefaultActionDiscoveryConventions

{

    public override bool IsController(TypeInfo typeInfo)

    {

        var isController = base.IsController(typeInfo);

        return isController || typeInfo.Name.Equals(“Poco”, StringComparison.OrdinalIgnoreCase);

    }

}

To make MVC use this class we have to register it with built-in dependency injection system, We will do it in ConfigureServices() method of our Startup class by calling AddTransient() method.

public void ConfigureServices(IServiceCollection services)

{

    // …

    services.AddMvc();

 

    services.AddTransient<IActionDiscoveryConventions, MyActionDiscoveryConventions>();

}

If we run our application now and try to use POCO controller it works again.

Defining ControllerAttribute

If you are building some extensible system and you need some better way how to detect controllers then besides naming controllers appropriately you can also define attribute in some API library that is available for developers.

public class ControllerAttribute : Attribute

{

}

Other developers who are building plugins for your system can decorate their controllers with this attribute.

[Controller]

public class Poco

{

    // …

}

And here is how you can detect controller in action discovery convention.

public class MyActionDiscoveryConventions : DefaultActionDiscoveryConventions

{

    public override bool IsController(TypeInfo typeInfo)

    {

        var isController = base.IsController(typeInfo);

        return isController || HasControllerAttribute(typeInfo);

    }

 

    private bool HasControllerAttribute(TypeInfo typeInfo)

    {

        return typeInfo.GetCustomAttribute<ControllerAttribute>(true) != null;

    }

}

You can also use marker interface for POCO controllers or some interface with properties and methods defined if your POCO controllers have to provide some functionalities.

Wrapping up

Creating POCO controllers is simple. To use views and other goodies provided by controllers base class we have to use dependency injection to get required services to our POCO controller. If we don’t use MVC regular naming style for controllers we have to write action discovery convention and register it with built-in dependency injection service. To provide common strategy to detect POCO controllers with arbitrary names we can use special attribute or interface for this. We still can inherit our POCO controllers from classes we want.

The post ASP.NET 5: Using POCO controllers appeared first on Gunnar Peipman - Programming Blog.

Topics:

Published at DZone with permission of Gunnar Peipman, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}