Search code examples
c#inversion-of-controlstructuremapasp.net-core-3.1lamar

StructureMap -> Lamar .NET Core 3.1 service creation not working


I am trying to migrate from StructureMap to Lamar (4.1.0) on the latest dotnet core release (3.1)

This project worked before the switch to Lamar, but so much has changed I am getting a touch lost.

Question?
After the scan occurs, how can I create an instance of an object with a constructor of an object that has already been scanned. I understand that StructureMap is a bit different, but this code worked previously.

Code below:

Startup.cs (attempt at new Lamar)


var container = new Container(cfg =>
{
    cfg.Scan(scanner =>
    {
        scanner.AssembliesAndExecutablesFromApplicationBaseDirectory(a => a.FullName.Contains("Project.Name.Here"));
        scanner.WithDefaultConventions();
        scanner.SingleImplementationsOfInterface();
    });


    cfg.For<IServerInformationDataAccess>()
        .Use(new ServerInformationDataAccess(Configuration.GetConnectionString(DbConnectionKey), Container.GetInstance<IMapper>()));

Startup.cs (old one that worked)

New Lamar (4.1) does not allow me to create without parameters anymore

Tried all of the instantiations but they did not work... so here I am

var container = new Container();

container.Configure(cfg =>
{
    cfg.Scan(s =>
    {
        s.AssembliesAndExecutablesFromApplicationBaseDirectory(a => a.FullName.Contains("Project.Name.Here"));
        s.WithDefaultConventions();
        s.SingleImplementationsOfInterface();
    });

    cfg.For<IServerInformationDataAccess>()
        .Use<ServerInformationDataAccess>(sida => new ServerInformationDataAccess(Configuration.GetConnectionString(DbConnectionKey), container.GetInstance<IMapper>()));

Program.cs


public class Program
{
    public static void Main(string[] args)
    {
        CreateHostBuilder(args).Build().Run();
    }

    public static IHostBuilder CreateHostBuilder(string[] args) =>
        Host.CreateDefaultBuilder(args)
            .UseLamar()
            .ConfigureWebHostDefaults(webBuilder =>
            {
                webBuilder.UseStartup<Startup>();
            });
}

Solution

  • In this case the Use acts as the factory delegate

    //...
    
    cfg.For<IServerInformationDataAccess>()
        .Use<ServerInformationDataAccess>(c => { //<-- c in this case is a container context
            var connectionString = Configuration.GetConnectionString(DbConnectionKey);
            var mapper = c.GetInstance<IMapper>();
            return new ServerInformationDataAccess(connectionString, mapper);
        });
    
    //...
    

    Reference Building Objects with Lambdas