Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add fluent extension method for options classes so that we can create instances conveniently. #120

Merged
merged 2 commits into from
Jan 27, 2018

Conversation

edwardmeng
Copy link
Contributor

No description provided.

@ejsmith
Copy link
Contributor

ejsmith commented Jan 27, 2018

This looks pretty good @edwardmeng. Only thing I was thinking different was to use a separate OptionsBuilder where all the extension methods live off of that so that they don't pollute the actual options object itself:

public class OptionsBuilder<T> where T: class, new() {
    public T Target { get; } = new T();
}

public class MyImp {
    private readonly MyImpOptions _options;

    public MyImp(ConfigureOptions<MyImpOptions> builder)
        : this(builder(new OptionsBuilder<MyImpOptions>()).Target) {}

    public MyImp(MyImpOptions options) {
        _options = options;
    }
}

public delegate OptionsBuilder<T> ConfigureOptions<T>(OptionsBuilder<T> builder) where T: class, new();

public class MyImpOptions {
    public string SomeOption { get; set; }
}

public static class MyImpOptionsBuilder {
    public static OptionsBuilder<MyImpOptions> WithSomeOption(this OptionsBuilder<MyImpOptions> builder, string someOption) {
        builder.Target.SomeOption = someOption;
        return builder;
    }
}

public static class Startup {
    public static void Main() {
        var myImp = new MyImp(b => b.WithSomeOption("value"));

        var myImp2 = new MyImp(new MyImpOptions { SomeOption = "value" });
    }
}

@ejsmith
Copy link
Contributor

ejsmith commented Jan 27, 2018

I’ve always been torn on fluent builder methods being prefixed with something like o => o.WithSomeOption() vs just having o => o.SomeOption(). What do you guys think @edwardmeng @niemyjski ?

@edwardmeng
Copy link
Contributor Author

@ejsmith I have completed the changes as your suggestion, please review again.

@ejsmith
Copy link
Contributor

ejsmith commented Jan 27, 2018

Looks good except I like creating a delegate so that the ctors get a little simler and go from:

public InMemoryFileStorage(Action<IOptionsBuilder<InMemoryFileStorageOptions>> config)
    : this(OptionsBuilder<InMemoryFileStorageOptions>.Build(config)) { }

to

public delegate OptionsBuilder<T> ConfigureOptions<T>() where T: class, new();

public InMemoryFileStorage(ConfigureOptions<InMemoryFileStorageOptions> config)
    : this(OptionsBuilder<InMemoryFileStorageOptions>.Build(config)) { }

@edwardmeng
Copy link
Contributor Author

I have tried as your suggestion, but the ConfigureOptions cannot be defined covariant between base options and inherited options.

@ejsmith
Copy link
Contributor

ejsmith commented Jan 27, 2018

Ok then I think it’s good to go.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants