« Back to home

Resolving the StructureMap.ObjectFactory is obsolete warning message.

Posted on

If you're using StructureMap 3.1.x for your IoC container for .NET, you might have encountered the message, "StructureMap.ObjectFactory is obsolete: 'ObjectFactory will be removed in a future 4.0 release of StructureMap. Favor the usage of Container class for future work'"

The old way of configuring the StructureMap dependency resolver was to do something like:

public IContainer Container  
{
    get
    {
    return (IContainer)HttpContext.Current.Items["_Container"];
    }
    set
    {
    HttpContext.Current.Items["_Container"] = value;
    }
}

DependencyResolver.SetResolver(new SMDependencyResolver(() => Container ?? ObjectFactory.Container));

            ObjectFactory.Configure(cfg =>
            {
                cfg.AddRegistry(new StandardRegistry());
                cfg.AddRegistry(new ControllerRegistry());
                cfg.AddRegistry(new ActionFilterRegistry(() => Container ?? ObjectFactory.Container));
                cfg.AddRegistry(new MvcRegistry());
                cfg.AddRegistry(new TaskRegistry());
                cfg.AddRegistry(new ModelMetadataRegistry());
            });

The object factory then allows the registry of dependencies either in your global.asax or some static class instance within your solution.

In order to get rid of this message, one possible solution that I've found online was the pass in an instance of IContainer in the controller if you're using ASP.NET MVC or Web API.

public class MyController  
{
    public MyController(IContainer container)
    {    
    }
}

Perhaps a better (or cleaner approach) is to re-define a new ObjectFactory that a returns an IContainer static instance.

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 =>
    {
        x.AddRegistry(new StandardRegistry());
        cfg.AddRegistry(new ControllerRegistry());
        x.AddRegistry(new ActionFilterRegistry(
          () => Container ?? Infrastructure.ObjectFactory.Container));
        cfg.AddRegistry(new MvcRegistry());
        x.AddRegistry(new TaskRegistry());
        cfg.AddRegistry(new ModelMetadataRegistry());
    });
  }
}

In the global.asax, you can get the ObjectFactory.Container instance using:

var container = Infrastructure.ObjectFactory.Container;  

The container variable can then be used to extend and configure additional dependencies and settings.

Comments

comments powered by Disqus