37

When implementing DI in WebAPI with StructureMap, we used the ServiceActivator found in


public class ServiceActivator : IHttpControllerActivator
{
    public ServiceActivator(HttpConfiguration configuration) {}    

    public IHttpController Create(HttpRequestMessage request,
           HttpControllerDescriptor controllerDescriptor, Type controllerType)
    {
        var controller = ObjectFactory.GetInstance(controllerType) as IHttpController;
        return controller;
    }
}

But now with the new StructureMap, my ReSharper suggested:

Class 'StructureMap.ObjectFactory' is obsolete: ObjectFactory will be removed in a future 4.0 release of StructureMap. Favor the usage of the Container class for future work

The intellisense on Container gave me only very limited information.

How are we supposed to rewrite our ServiceActivator with the Container class?

Community
  • 1
  • 1
Blaise
  • 21,314
  • 28
  • 108
  • 169

1 Answers1

39

The static stuff is going away. If your not using a Service Locator of some type you're going to have implement your own "ObjectFactory" as referenced here:

public static class ObjectFactory
{
    private static readonly Lazy<Container> _containerBuilder =
            new Lazy<Container>(defaultContainer, LazyThreadSafetyMode.ExecutionAndPublication);

    public static IContainer Container
    {
       get { return _containerBuilder.Value; }
    }

     private static Container defaultContainer()
     {
        return new Container(x =>
        {
               // default config
         });
     }
}

Update: My previous answer was wrong. Thanks @JoeMighty for the heads up.

Steve Dunn
  • 21,044
  • 11
  • 62
  • 87
mxmissile
  • 11,464
  • 3
  • 53
  • 79
  • 1
    Surely this just creates a new instance of an empty container? From my experience that seems to be the case. – Joseph Woodward Oct 24 '14 at 09:22
  • @JoeMightly To quote the author "ObjectFactory is just a static facade over Container anyway". However, I will throw up a gist later today that proves this. – mxmissile Nov 06 '14 at 14:08
  • I've read this too; however I seem to end up with an empty container. A gist demonstrating this would be greatly appreciated! – Joseph Woodward Nov 06 '14 at 14:11
  • 1
    @JoeMighty You are correct! I used Service Locator and/or the built in MVC DependencyResolver for resolution with SM3, so I never ran into this problem. However after several tests, as far as I can tell I end up with empty containers like you noted. – mxmissile Nov 06 '14 at 17:23
  • Ok, thanks for clarifying and updating your answer! It's good to know I wasn't going crazy. Another pattern I've noticed is to store the container in `HttpContext.Items`. – Joseph Woodward Nov 07 '14 at 01:43
  • why is ObjectFactory going away? I understand that most of its usages are wrong: service location anti-pattern; using a top-level container on a nested-container environment; (...). In some cases, such as having an IHttpModule for instance, that needs to get something from the IContainer and it's not DI-friendly, what's the suggested approach? I don't want to move my composition root and I want to use the same container context – Ricardo Rodrigues Mar 12 '15 at 16:11
  • @RicardoRodrigues I believe the gist is that ObjectFactory promotes the [service locator anti pattern](http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/) – Eddie Groves May 07 '15 at 02:14
  • @eddiegroves An IoC container is a very sharp tool, you can't just polish the edges, needs to be sharp, it's meant to be used by experienced developers. If you take the sharpness, this happens. – Ricardo Rodrigues May 07 '15 at 08:14
  • 3
    Service location is not and has not ever been an anti-pattern. Usage of the pattern incorrectly does not make the pattern itself wrong. – Chris Marisic Oct 30 '15 at 20:21
  • What is supposed to go in //default config? I'm just trying to upgrade structuremap, and now our entire applications codebase is broken! This is going to take days of work. – Tyler Jones Jul 18 '17 at 18:11
  • @TylerJones Are you using a Registry to config SM? – mxmissile Jul 18 '17 at 19:40
  • Yes, we are using a registry. – Tyler Jones Jul 18 '17 at 19:52
  • @TylerJones just add this then: `x.AddRegistry();` where it says // default config MyRegistry being your registry type – mxmissile Jul 18 '17 at 19:53
  • @TylerJones let me know if that worked or not, I can help you offline if you still get stuck – mxmissile Jul 18 '17 at 20:52