Search code examples
model-view-controllerdependency-injectionstructuremapcontroller-factory

what exactly ObjectFactory is, and, whats is it used for?


this is my StructureMapControllerFactory which i want to use it in mvc5 project

public class StructureMapControllerFactory : DefaultControllerFactory
{
    private readonly StructureMap.IContainer _container;

    public StructureMapControllerFactory(StructureMap.IContainer container)
    {
        _container = container;
    }

    protected override IController GetControllerInstance(
        RequestContext requestContext, Type controllerType)
    {
        if (controllerType == null)
            return null;

        return (IController)_container.GetInstance(controllerType);
    }
}

i configured my controller factory in the global.asax like this:

public class MvcApplication : System.Web.HttpApplication
{
    protected void Application_Start()
    {

        var controllerFactory = new StructureMapControllerFactory(ObjectFactory.Container);

        ControllerBuilder.Current.SetControllerFactory(controllerFactory);
        AreaRegistration.RegisterAllAreas();
        RouteConfig.RegisterRoutes(RouteTable.Routes);
    }
}

but what is ObjectFactory? why i cant find any namespace about that? why iv got:

the name ObjectFactory doesnt exist in current context

i tried many methods of using controller factory and iv got this problem when i felt Object factory in code ...it really bored my


Solution

  • ObjectFactory was a static instance to the StructureMap container. It has been removed from StructureMap because it is not a good practice to access the container anywhere but in the application's composition root (which leads down the dark path to the service locator anti-pattern).

    So, to keep everything DI-friendly, you should pass the DI container instance, rather than using static methods.

    public class MvcApplication : System.Web.HttpApplication
    {
        protected void Application_Start()
        {
            // Begin composition root
    
            IContainer container = new Container()
    
            container.For<ISomething>().Use<Something>();
            // other registration here...
    
            var controllerFactory = new StructureMapControllerFactory(container);
    
            ControllerBuilder.Current.SetControllerFactory(controllerFactory);
            AreaRegistration.RegisterAllAreas();
            RouteConfig.RegisterRoutes(RouteTable.Routes);
    
            // End composition root (never access the container instance after this point)
        }
    }
    

    You may need to inject the container into other MVC extension points, such as a global filter provider, but when you do make sure that all of that is done inside of the composition root.