我的 MVC 自定义 ControllerFactory 可以工作,但还能更好吗?

2024-01-22

我研究过 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)
    {
    }
}

创建了我自己的控制器工厂,它允许我将 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 类注入到工厂中以注入到创建的控制器中。

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

        RegisterRoutes(RouteTable.Routes);

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

我唯一没有探索过的领域(而且我认为我目前对此不感兴趣)是创建一个web.config部分动态创建ModelFactory。这可行,但我感兴趣的是我是否完全错过了机会,是否接近,或者我是否恰到好处?


而不是重写 CreateController 使用

protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

我的 MVC 自定义 ControllerFactory 可以工作,但还能更好吗? 的相关文章

随机推荐