The correct way to implement StructureMap in .NET Core WebApi when having multiple projects

StructureMap is an IoC/DI container for .Net which has been a long time around. I’ve been using it for these past few years, and after all this time, I found out the correct way to implement it.

This is how I used it before and I’m sure the majority of you are currently using the same methods. In the Registry, I would register each interface and it’s inherited class by calling a “config.for” for each service as follows:

    config.For(typeof(ITestService)).Add(typeof(TestService));
    config.For(typeof(IUserService)).Add(typeof(UserService));
    config.For(typeof(ITenantService)).Add(typeof(TenantService));
    config.For(typeof(IProjectService)).Add(typeof(ProjectService));

And whenever new interfaces and services are added, they need to be registered using a new “config.for” line.

That was the old way, of how I did things. This is the new way.

One Project Solutions:

In the ConfigureIOC method (in Startup.cs class), if you add “_.WithDefaultConvetions()” method, it will search and register the interfaces and their inherited classes automatically if you use the default conventions (ex. naming the class ServiceName and the interface IServiceName). But this only works if you have all the interfaces and classes inherited in the same project.

Multi Project Solutions:

What about if you have your solution split into multiple projects, as it should be, to use StructureMap as the dependency injection? In the ConfigureIOC method (in Startup.cs class) you need to add the following calls adding the Assembly name for each project that you have in the solution:

    _.Assembly("Project.Api.Contracts");
    _.Assembly("Project.Api.Infrastructure");
    _.WithDefaultConventions();
    _.LookForRegistries();

This will add all the solution projects to the StructureMap “lookup”. Then by calling the LookForRegistries(), it will search the registries in all projects. In each project whose assembly names you specified, you need to install the StructureMap nuget package, and add the following Registry.cs class in the root of these projects:

using StructureMap;

namespace Project.Api.Infrastructure
{
    public class InfrastructureRegistry : Registry
    {
        public InfrastructureRegistry()
        {
            Scan(scan =>
            {
                scan.TheCallingAssembly();
                scan.WithDefaultConventions();

            });

            //any other spefic implementation   
        }
    }
}

Each project will now scan for its own interfaces and inherited classes, and finally StructureMap will get the information from each project registries.

Following is the full code for the ConfigureIOC method in the Startup.cs class:

public IServiceProvider ConfigureIoC(IServiceCollection services)
{
    var container = new Container();

    container.Configure(config =>
    {
        // Register stuff in container, using the StructureMap APIs...
        config.Scan(_ =>
        {
            _.AssemblyContainingType(typeof(Startup));
            _.Assembly("Project.Api.Contracts");
            _.Assembly("Project.Api.Infrastructure");
            _.WithDefaultConventions();
            _.LookForRegistries();
        });

        //Populate the container using the service collection
        config.Populate(services);
    });

    return container.GetInstance<IServiceProvider>();
}

Now anytime you need to add a new interface and it’s inherited class, you don’t need to add anything in the Registry class, because StructureMap will find it by itself 🙂

 

References – here and here

Hello, nice to meet you

Enter your email address to subscribe to this blog and receive notifications of new posts by email.

1 Comments

Leave a Reply