My MVC Custom ControllerFactory works but could it be better?

混江龙づ霸主 提交于 2021-02-08 02:36:10

问题


I've looked at Ninject, StructureMap and Other Dependency Injection and Service Locator frameworks, but this question is more about learning how it works and what can be better. More to the point, I’m not interesting in looking at a Framework’s source code for Dependency Injection, but understanding how it’s achieved from beginning to end in practice/code.

The code below is for a small internal project, so with that in mind let me begin.

Here is my interface for returning Domain Models to my controllers. I've decided that due to the size of the project (small), a single interface for Controllers was acceptable.

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

Each controller has inherits from DIBaseController so I didn't have to create private members for every controller.

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)
    {
    }
}

Created my own Controller Factory that allows me to inject my ModelFactory into Controllers.

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

And finally added the code to Inject the Concreate class into the Factory to inject into created Controllers.

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

        RegisterRoutes(RouteTable.Routes);

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

The only area I haven't explored (and I don't think I'm interested in at the moment) is to create a web.config section to dynamically create the ModelFactory. This works, but I'm interested if I've completely missed the boat, come close, or if I'm spot on?


回答1:


Instead of overriding CreateController use

protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)

It gives you the controller type and the first part of your implementation is obsolete.

The next point you have to improve is that you analyze the parameters of the constructor and pass an instance of those parameters which are created using some configuration instead of guessing that there is exactly one parameter IModelFactory.



来源:https://stackoverflow.com/questions/4290687/my-mvc-custom-controllerfactory-works-but-could-it-be-better

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!