StructureMap and ASP .Net Web API and .Net Framework 4.5
Asked Answered
P

2

9

Does the current version of StructureMap support ASP .Net Web API, MVC 4 and .NET Framework 4.5?

Prophase answered 9/8, 2012 at 17:58 Comment(0)
S
14

As outlined here, the web API uses a dependency resolver.

class StructureMapDependencyResolver : IDependencyResolver
{
    public IDependencyScope BeginScope()
    {
        return this; 
    }

    public object GetService(Type serviceType)
    {
        return ObjectFactory.GetInstance(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        return ObjectFactory.GetInstances(serviceType);
    }

    public void Dispose()
    {
    }
}

And in your Global.asax.cs, include this line to register the dependency resolver:

GlobalConfiguration.Configuration.DependencyResolver = new StructureMapDependencyResolver();

Aside from that, the new Web API is very easy to use with IoC containers.

I haven't looked into it yet, but I believe the BeginScope method that I left blank can be used with child containers.

Edit:

The above implementation works great; in fact I prefer it over the alternative I'm about to tell you. This one will resolve any Type to the best of StructureMap's abilities and will throw errors whenever something goes wrong. I like seeing errors because they show me what I did wrong.

However, the API expects that GetService will return null if something goes wrong. So to be compliant with the API, this is the recommended implementation:

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

The difference is that TryGetInstance only looks for types registered in the container and will return null if something goes wrong. serviceType.IsAbstract || serviceType.IsInterface is considered good enough of a check to decide which method to use. My original answer was intended to be straightforward and simple, but @PHeiberg points out in the comments here that it wasn't entirely "correct". Now that you have knowledge, use whatever seems best.

Subglacial answered 11/8, 2012 at 0:27 Comment(5)
StructureMap doesn't handle dependency resolution like expected here. Check out this example and the comments by Jeremy: ardalis.com/How-Do-I-Use-StructureMap-with-ASP.NET-MVC-3Caseation
Actually this will work. Jeremy says TryGetInstance only resolves if serviceType is explicitly registered. GetInstance still will resolve types that aren't registered but are concrete.Subglacial
The resolution of instances will work with your code. However I interpret the link I posted as the proposed "Best Practice", since Jeremy himself recommends it. I guess that GetService method is supposed to return null, instead of generating an exception if the type is not resolvable by the container.Caseation
This answer put me on the right track. I found a blog post which goes a few more steps: ericsowell.com/blog/2011/1/20/…Diller
One minor amendment (unless the API has changed in v5, I'm using v4), your StructureMapDependencyResolver is missing an 'IDependencyScope' declarationThallium
C
8

ASP.NET Web API Release version uses dependency resolver (implementation of IDependencyResolver interface) and it introduces also new concept - dependency scope (implementation of IDependencyScope interface). It is important to implement IDependencyScope properly - if implemented properly, it allows to release resources (created in scope) when IDependencyScope is disposed. And it is disposed when request ends.

IDependencyScope works best when container supports nested (or child) containers. StructureMap does it from version 2.6.1.

I wrote an article how to configure StructureMap in Web API: Configuring StructureMap in ASP.NET WebAPI

You also can check article from Mike Wasson: Using the Web API Dependency Resolver

Cachucha answered 29/8, 2012 at 19:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.