2

I am in the process of integrating StructureMap into my MVC3 application. I am running into a problem where my custom ControllerFactory is throwing an exception when attempting to create a controller:

StructureMap Exception Code: 200 Could not find an Instance named "contentpage" for PluginType System.Web.Mvc.IController

Here’s what I have in the container:

Controller (System.Web.Mvc.Controller)
Scoped as: Transient

AuctionCMS.Web.Controllers.HomeController, AuctionCMS.Web, Version=1.0.0.0, Culture=neutral,

AuctionCMS.Web.Controllers.ContentPageController, AuctionCMS.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null Configured Instance of AuctionCMS.Web.Controllers.ContentPageController, AuctionCMS.Web, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

I did notice that the controller factory is requesting “contentpage” instead of “contentpagecontroller.” Is this correct behavior? What is going wrong?

Here’s my code:

    private void InitStructureMap()
    {
        var container = new StructureMap.Container();

        DependencyResolver.SetResolver(new StructureMapContainer(container));
        ControllerBuilder.Current.SetControllerFactory(new StructureMapControllerFactory(container));

        PerformRuntimeDepdendencyConfiguration(container);
    }



    private void PerformRuntimeDepdendencyConfiguration(IContainer container)
    {
        container.Configure(x => x.Scan(y =>
        {
            y.TheCallingAssembly();
            y.WithDefaultConventions();
            y.LookForRegistries();
            y.AddAllTypesOf<Controller>();
        }));
    }



public class StructureMapContainer : IDependencyResolver
{
    static IContainer _container;

    public StructureMapContainer(IContainer container)
    {
        _container = container;
    }

    public object GetService(Type serviceType)
    {
        if (serviceType.IsAbstract || serviceType.IsInterface)
        {
            return _container.TryGetInstance(serviceType);
        }
        else
        {
            return _container.GetInstance(serviceType);
        }
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return _container.GetAllInstances<object>().Where(s => s.GetType() == serviceType);
    }
}


    public class StructureMapControllerFactory : IControllerFactory
    {
        private readonly IContainer _container;

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

        public IController CreateController(RequestContext requestContext, string controllerName)
        {
            System.Diagnostics.Debug.WriteLine(_container.WhatDoIHave()); 

            return _container.GetInstance<IController>(controllerName.ToLowerInvariant());
        }

        public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
        {
            return SessionStateBehavior.Default;
        }

        public void ReleaseController(IController controller)
        {
            return;
        }
    }

public class ApplicationRegistry : Registry
{
    public ApplicationRegistry()
    {
        ... register some types ...
    }
}
5
  • Have you confirmed that your controllers are picked up properly by the scan? Commented Mar 29, 2012 at 20:35
  • You can see that above in the dump of the container Commented Mar 30, 2012 at 1:32
  • Ah sorry I missed that. I don't see the name in your output but I suspect you just need to append "controller" to your controller name - could be the convention you are using isn't trimming that off. Commented Mar 30, 2012 at 1:41
  • I tried that too, no go. I don't think the container is configured to look up instances by name. Commented Mar 30, 2012 at 15:14
  • I think that using nameby should work. There's also a method on ControllerFactory that takes a type IIRC, you aren't really doing any special naming so that probably could've worked here too. Commented Apr 4, 2012 at 2:15

1 Answer 1

1

Like you noted in comments, your controllers aren't registered by name. Try this:

container.Configure(x => x.Scan(y =>
{
    y.TheCallingAssembly();
    y.WithDefaultConventions();
    y.LookForRegistries();
    y.AddAllTypesOf<Controller>()
         .NameBy(type => type.Name.Replace("Controller", "")
         .ToLowerInvariant());
}));
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.