加载/选择“控制器”类的最佳方法是什么

时间:2010-11-22 11:47:26

标签: c# asp.net

我不确定我是否使用了正确的术语,但我有几个Controller类在ASP.NET Web应用程序中使用不同的数据源返回对象。即

Product p = ProductController.GetByID(string id);

我希望能够使用的控制器工厂可以从不同的ProductControllers中进行选择。我理解基本的工厂模式,但想知道是否有一种方法只使用一个字符串加载选定的cotroller类。

我想要实现的是一种返回新/不同控制器而无需更新工厂类的方法。有人建议我看一下依赖注入和MEF。我看了一下MEF,但我一直无法弄清楚如何在网络应用程序中实现这一点。

我想在正确的方向上找到一些指示。

1 个答案:

答案 0 :(得分:1)

有很多方法可以解决这个问题。你不需要一个框架来进行依赖注入(虽然手工编码可能会让你达到IoC容器开始有意义的程度)。

由于你想在多个实现上调用GetByID,我首先要从你拥有的ProductController中提取一个接口。

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

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

从那里你可以通过多种方式解决实现,例如:

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();
        }
     }
}

这一切取决于谁将负责选择需要使用哪个ProductController实现。