【问题标题】:My MVC Custom ControllerFactory works but could it be better?我的 MVC 自定义 ControllerFactory 可以工作,但它会更好吗?
【发布时间】:2010-11-27 08:08:55
【问题描述】:

我看过 Ninject、StructureMap 和其他依赖注入和服务定位器框架,但这个问题更多的是关于了解它的工作原理以及哪些方面可以做得更好。更重要的是,我对查看框架的依赖注入源代码并不感兴趣,而是了解它是如何在实践/代码中从头到尾实现的。

下面的代码是针对一个小型内部项目的,所以让我开始吧。

这是我将域模型返回到我的控制器的界面。我已经决定,由于项目的规模(小),控制器的单一界面是可以接受的。

interface IModelFactory
{
    IEnumerable<User> GetUsers();
    User GetUser(Guid UserID);
    bool Add(User User);
    bool Delete(User User);
    bool Update(User User);
    IEnumerable<Car> GetCars();
    Car GetCar(Guid CarID);
    bool Add(Car Car);
    bool Delete(Car Car);
    bool Update(Car Car);
}

每个控制器都继承自 DIBaseController,因此我不必为每个控制器创建私有成员。

public abstract class DIBaseController : Controller
{
    protected IModelFactory ModelFactory { get; set; }

    public DIBaseController(IModelFactory ModelFactory)
    {
        this.ModelFactory = ModelFactory;
    }
}

public class HomeController : DIBaseController
{
    public HomeController (IModelFactory ModelFactory)
        : base(ModelFactory)
    {
    }
}

创建了我自己的控制器工厂,允许我将我的模型工厂注入控制器。

internal class DIControllerFactory : DefaultControllerFactory 
{
    private IModelFactory _ModelFactory;

    internal DIControllerFactory(IModelFactory ModelFactory)
    {
        this._ModelFactory = ModelFactory;
    }

    public override IController CreateController(RequestContext requestContext, string controllerName)
    {
        IController result = null;
        string thisnamespace = this.GetType().Namespace;
        //This could be improved I bet.
        Type controller = Type.GetType(thisnamespace.Substring(0, thisnamespace.IndexOf('.')) + ".Controllers." + controllerName + "Controller");

        if (controller != null
            && controller.IsSubclassOf(typeof(DIBaseController)))
        {
            result = (IController)Activator.CreateInstance(controller, new object[] { this._ModelFactory });
        }
        else
        {
            result = base.CreateController(requestContext, controllerName);
        }

        return result;
    }
}

最后添加代码将Concreate类注入Factory,注入到创建的Controllers中。

    protected void Application_Start()
    {
        AreaRegistration.RegisterAllAreas();

        RegisterRoutes(RouteTable.Routes);

        ControllerBuilder.Current.SetControllerFactory(new DIControllerFactory(new LinqSqlModelFactory()));
    }

我没有探索的唯一领域(我认为我目前不感兴趣)是创建一个web.config 部分来动态创建ModelFactory。这行得通,但如果我完全错过了船,靠近,或者如果我在现场,我很感兴趣?

【问题讨论】:

    标签: asp.net-mvc-2 dependency-injection


    【解决方案1】:

    而不是覆盖 CreateController 使用

    protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
    

    它为您提供控制器类型,而您的实现的第一部分已过时。

    您需要改进的下一点是您分析构造函数的参数并传递使用某些配置创建的这些参数的实例,而不是猜测只有一个参数 IModelFactory。

    【讨论】:

    • 哦,这信息太棒了!对于其他任何人,stackoverflow.com/questions/1799214/… 上的 GetControllerInstance 有更多详细信息。
    • 由于项目很小,我不想用Reflection来确定需要的参数,但我也想创建不需要IModelFactory的控制器,这就是为什么代码@ 987654324@ 存在。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多