user20358
user20358

Reputation: 14766

Controller reuse in asp.net mvc

I have a two different projects that are actually two different websites when deployed, say WebA & WebB. The structure of both websites is the same in terms of the controllers and models they use. However, the front end is very different. They each have their own UI and own jquery plugins that work for them.

To reduce code duplication, I am proposing both those projects inherit from controllers in another referenced project[controllerDLL]. ControllerDLL is a project that will have all the logic for calling the business layer and returning json serialized model objects. WebA & WebB will each just have empty controller classes that just inherit from the base project[controllerDLL]. This way I feel the controller code is not duplicated.

Can anyone tell me a better way to achieve controller reuse other than the way I have proposed? Does asp.net mvc 4 provide any built-in way to do this better? Can I use AREAS here productively? Is DotNetNuke something I should look at? Or is my approach the best way forward? I am not looking for the how to move controllers into another project. I just want to know what my options are for achieving controller reuse.

Thanks.

Upvotes: 4

Views: 2307

Answers (3)

Ody
Ody

Reputation: 2047

Since the difference between the two applications are the views, you don't need to have them as separate projects. you could have two sets of views and deploy the same project twice using different settings in the web config. To do this, you'll have to implement your own ViewEngine so that the controller can return the correct right views.

public class AppSettingViewEngine: RazorViewEngine
{
    public AppSettingViewEngine()
    {
        string[] viewLocations = new string[] { };
        if (ConfigurationManager.AppSettings["Site"] == "WebA")
        {
            viewLocations = new[] {  
                "~/WebB/Views/{1}/{0}.cshtml",  
                "~/WebB/Views/{1}/{0}.cshtml",  
                "~/WebB/Views/Shared/{0}.cshtml",  
                "~/WebB/Views/Shared/{0}.cshtml",
            };
        }
        if (ConfigurationManager.AppSettings["Site"] == "WebB")
        {
            viewLocations = new[] {  
                "~/WebB/Views/{1}/{0}.cshtml",  
                "~/WebB/Views/{1}/{0}.cshtml",  
                "~/WebB/Views/Shared/{0}.cshtml",  
                "~/WebB/Views/Shared/{0}.cshtml",
            };
        }
        else
        {
            //Default Settings
            viewLocations = new[] {  
                "~/Views/{1}/{0}.cshtml",  
                "~/Views/{1}/{0}.cshtml",  
                "~/Views/Shared/{0}.cshtml",  
                "~/Views/Shared/{0}.cshtml",
            };
        }

        this.PartialViewLocationFormats = viewLocations;
        this.ViewLocationFormats = viewLocations;
    }
}

Then you register it in your Application_Start as follows

protected void Application_Start()
{
    ViewEngines.Engines.Clear();
    ViewEngines.Engines.Add(new AppSettingViewEngine());
}

Upvotes: 0

Vasanth
Vasanth

Reputation: 1710

You should be able to achieve this by implementing custom controller factory to instantiate the right controller class based on config settings.

You need to implement the interface System.Web.Mvc.IControllerFactory.The two methods in this interface are:

1.System.Web.Mvc.IController CreateController(System.Web.Routing.RequestContext requestContext, string controllerName) - To create the controller instance based on RequestContext and controller name.

2.void ReleaseController(System.Web.Mvc.IController controller) - Release the controller instance

Detailed information about using that interface is available

Upvotes: 2

Becuzz
Becuzz

Reputation: 6857

Take a look at this SO question. You could keep all the views in the same project and use a custom view engine to find the views (based off a web.config setting).

For example you could have 2 folders /Views/WebA and /Views/WebB. The custom view engine could look up the web.config setting to find out which folder to use and search for the views there. This way you would not have to duplicate the controller code or move it into a separate project. It will just swap out one presentation layer for another at runtime.

Upvotes: 2

Related Questions