Search code examples
c#asp.net-coreasp.net-core-2.0startup

Read properties of options builder in IServiceCollection extension method


I have an extension method on IServiceCollection that looks like this:

public static IServiceCollection AddMyProjData(this IServiceCollection services, Action<MyProjDataOptionsBuilder> optionsBuilder)
{
    services.Configure(optionsBuilder);

    services.AddDbContext<MyProjDbContext>(contextOptions => contextOptions
        .UseLazyLoadingProxies()
        .UseMySql("?????")
    );

    return services;
}

The class MyProjOptionsBuilder looks like this:

public class MyProjDataOptionsBuilder
{
    public string ConnectionString { get; set; }
}

How can I get to the property ConnectionString inside my extension method?

I want to do something like this:

var connectionString = optionsBuilder().ConnectionString;

PS.

I know I can directly pass a string as parameter instead of an Action to the extension method AddMyProjData. But in my real project I need to set a lot more settings than just one ConnectionString.

I also like the style of using an Action to configure the service.


Solution

  • You could just create an instance of MyProjDataOptionsBuilder inside AddMyProjData, apply optionsBuilder against that instance and then use the properties you need.

    Here's an example:

    public static IServiceCollection AddMyProjData(
        this IServiceCollection services,
        Action<MyProjDataOptionsBuilder> optionsBuilder)
    {
        var myProjDataOptionsBuilder = new MyProjDataOptionsBuilder();
        optionsBuilder(myProjDataOptionsBuilder);
    
        services.Configure(optionsBuilder);
    
        services.AddDbContext<MyProjDbContext>(contextOptions => contextOptions
            .UseLazyLoadingProxies()
            .UseMySql(myProjDataOptionsBuilder.ConnectionString)
        );
    
        return services;
    }
    

    There's some repetition in terms of what's going on here (invoking optionsBuilder twice), but I wouldn't expect this to be a great cost overall.

    An alternative would be to separate your configuration-time and your runtime options - I doubt you're going to need the connection-string itself anywhere other than inside of your extension method, but I'm only guessing here.


    From what you've shown in your OP, I'm not convinced that MyProjDataOptionsBuilder is a great name (I'd probably just go with MyProjDataOptions), but that's mostly an aside here.