简体   繁体   中英

What is the best way to load/choose “controller” classes

I'm not sure if i'm using the correct terminology but I have several Controller classes that return objects using different data sources in my ASP.NET web app. ie

Product p = ProductController.GetByID(string id);

What I want to be able to do is use a controller factory that can select from different ProductControllers. I understand the basic factory pattern but wondered if there was a way to load the selected cotroller class using just a string.

What I want to achieve is a way of returning new/different controllers without having to update a factory class. Someone suggested i look at dependency injection and MEF. I had a look at MEF but I've been having trouble figuring out how to implment this in a web app.

I'd love to get some pointers in the right direction.

There are many ways to solve this. You don't need a framework to do dependency injection (though hand coding them may bring you to a point where the IoC containers start to make sense).

Since you want to call the GetByID on multiple implementations I'd start with extracting an interface from the ProductController you have.

    public interface IProductController
    {
        Product GetByID(int id);
    }

    public class SomeProductController : IProductController
    {
        public Product GetByID(int id)
        {
            return << fetch code >> 
        }
    }

From there you can resolve the implementation in a number of ways, some examples:

public class ProductFetcher
{
    // option 1: constructor injection
    private readonly IProductController _productController;

    public ProductFetcher(IProductController productController)
    {
        _productController = productController;
    }
    public Product FetchProductByID(int id)
    {
        return _productController.GetByID(id);
    }

    // option 2: inject it at the method level
    public static Product FetchProductByID(IProductController productController, int id)
    {
        return productController.GetByID(id);
    }

    // option 3: black box the whole thing, this is more of a servicelocator pattern
    public static Product FetchProductsByID(string controllerName, int id)
    {
        var productController = getProductController(controllerName);
        return productController.GetByID(id);
    }

    private static IProductController getProductController(string controllerName)
    {
        // hard code them or use configuration data or reflection
        // can also make this method non static and abstract to create an abstract factory
        switch(controllerName.ToLower())
        {
            case "someproductcontroller":
                return new SomeProductController();
            case "anotherproductcontroller":
                // etc

            default:
                throw new NotImplementedException();
        }
     }
}

It all sort of depends on who's going to be responsible for selecting which ProductController implementation needs to be used.

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