6

very new to Structure-Map. trying to figure it out how it works and how can i benefit from it.

i have got this so far..

Global.asax.cs:

IContainer container = new Container(x =>
    {
         x.For<IControllerActivator>().Use
              <StructureMapControllerActivator>();
         x.For<IUserRepo>().Use<UserRepo>();
    }); 

DependencyResolver.SetResolver(new StructureMapDependencyResolver(container));

StructureMapControllerActivator:

public class StructureMapControllerActivator : IControllerActivator
{
    private readonly IContainer _container;

    public StructureMapControllerActivator(IContainer container )
    {
        this._container = container;
    }

    public IController Create(RequestContext requestContext, Type controllerType)
    {
        return _container.GetInstance(controllerType) as IController;
    }
}

StructreMapDependencyResolver:

private readonly IContainer _container;

    public StructureMapDependencyResolver(IContainer container )
    {
        this._container = container;
    }

    public object GetService(Type serviceType)
    {
        object instance = _container.TryGetInstance(serviceType);
        if(instance == null && !serviceType.IsAbstract)
        {
            _container.Configure(c => c.AddType(serviceType,serviceType));
            instance = _container.TryGetInstance(serviceType);
        }
        return instance;
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return _container.GetAllInstances(serviceType).Cast<object>();
    }
}

My AccountController:

public class AccountController : Controller
{
    private readonly IUserRepo _userRepo;

    private AccountController()
    {
        _userRepo = ObjectFactory.GetInstance<IUserRepo>();
    }

    public ActionResult Login()
    {
        return View();
    }
}

Error Code & Description:

StructureMap Exception Code: 202 No Default Instance defined for PluginFamily MBP_Blog.Controllers.AccountController MBP-Blog, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null

I have a Interface Name : IUserRepo and a repository Name: UserRepo

please help as I try to google but dint find any solution within first 3 pages.

New error after using @Martin's code:

StructureMap Exception Code: 180 StructureMap cannot construct objects of Class MBP_Blog.Controllers.AccountController, MBP-Blog, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null because there is no public constructor found.

abatishchev
  • 98,240
  • 88
  • 296
  • 433
patel.milanb
  • 5,822
  • 15
  • 56
  • 92

1 Answers1

3

Take out the StructureMapControllerActivator, I don't think you need it. If you keep it, you need to add a mapping for your AccountController.

Also, use Controller Injection instead, it will make unit testing easier:

public class AccountController : Controller
{
    private readonly IUserRepo _userRepo;

    public AccountController(IUserRepo userRepo)
    {
        _userRepo = userRepo;
    }

    public ActionResult Login()
    {
        return View();
    }
}

Also again, for your Container, you can default the mappings. This will automatically map IService to Service :

IContainer container = new Container(
            x =>
                {
                    x.Scan(scan =>
                               {
                                   scan.Assembly("MBP_Blog");
                                   scan.Assembly("MBP_Blog.Data");
                                   scan.WithDefaultConventions();
                               });
                });
Martin
  • 11,031
  • 8
  • 50
  • 77
  • @martin.. thanks for your answer..i tried using your method..but still i am getting the error. please look at the updated error.. – patel.milanb Sep 30 '11 at 12:57
  • thanks...somehow i got it working ...i dont know whether its a best practice tthanks for your help..o use it or not..will ask another question on that ... – patel.milanb Sep 30 '11 at 13:23
  • 2
    I believe it should called as "Constructor Injection" instead of "Controller Injection" – Teoman shipahi Sep 28 '14 at 00:32