简体   繁体   中英

C# Pass parameter to method using lambda expression

Anyone that used ASP.Net might have seen methods that accept an Action<T> delegate that is used to configure some options. Take this one as an example in a ASP.Net Core MVC Startup.cs.

public void ConfigureServices(IServiceCollection services)
{
    services.AddAuthentication().AddJwtBearer(options => {
        options.Audience = "something";
        // ...
    });

    //...
}

The .AddJwtBearer() method takes an Action<T> delegate with the configured parameters inside the lambda expression , what I'm trying to do is replicate that in one of my projects, but with no luck. I got the Method(Action<T> action) part down, but I can't seem to retrieve the resulting object that was configured when the method was called.

Some code for context:

The builder class method:

public ReporterBuilder SetEmail(Action<EmailConfig> config)
{
    if (config is null)
        throw new ArgumentNullException();

    // Get configured EmailConfig somehow...

    return this;
}

The EmailConfig model:

public class EmailConfig
{
    public EmailProvider EmailProvider { get; set; }
    public string Host { get; set; }
    public int Port { get; set; }
    public string Username { get; set; }
    public string Password { get; set; }
    public string FromAddress { get; set; }
    public string ToAddress { get; set; }
}

So what I'm trying to achieve here is this:

Reporter reporter = new ReporterBuilder()
    .SetEmail(config => {
        config.EmailProvider = EmailProvider.Other;
        config.Host = "something";
        // ...
    })
    .Build();

I looked at some Microsoft repositories on GitHub (aspnet/DependencyInjection, aspnet/Options seen to be the two main ones that use this approach with their IoC container) to see how they do to grab values from an Action<T> delegate, with absolutely no luck.

A few hours search on the internets didn't help either, as most articles are outdated or had nothing to do with what I'm trying to do.

Any help on how I can make this work is very welcome, also suggestions on better ways this can be done are also welcome.

Your method needs to instantiate the object, then call the method, passing the object into the method. A Func<T> would return an object. This is ActionT<T> , which doesn't return anything. Instead, it accepts the object.

public ReporterBuilder SetEmail(Action<EmailConfig> config)
{
    if (config == null)
        throw new ArgumentNullException();

    var cfg = new EmailConfig();

    // optionally populate the cfg with 
    // default configuration before calling method

    config(cfg);

    // cfg contains your configuration 
    // and is full of that thing called 'love'

    return this;
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM