Azure WebJobs SDK 3,尝试添加BlobTrigger和相关的连接字符串

问题描述 投票:2回答:4

旧的做事方式看起来如此:

        var jobConfig = new JobHostConfiguration(cfg.DocumentDatabase.BlobStorageServer)
        {
            NameResolver = new Support.BlobNameResolver(_env)
        };
        jobConfig.Queues.MaxPollingInterval = TimeSpan.FromSeconds(_pollSeconds);

        _wjHost = new JobHost(jobConfig);

我试图将其转换为3.0中的新方式,这就是我到底有多远:

        _wjHost = new HostBuilder().ConfigureWebJobs(b =>
        {
            b.AddAzureStorage(x =>
            {
                x.MaxPollingInterval = TimeSpan.FromSeconds(_pollSeconds);
            });
        }).ConfigureServices(s =>
        {
            s.AddSingleton<INameResolver, Support.BlobNameResolver>(_ => new Support.BlobNameResolver(_env));
            s.Configure<QueuesOptions>(o =>
            {
                o.MaxPollingInterval = TimeSpan.FromSeconds(_pollSeconds);
            });
        }).Build();

首先,我不知道哪个MaxPollingInterval是正确的使用...所以我设置了两个。我假设我不应该使用AddBlobStorage中的那个

其次,更重要的是,我在哪里指定blob存储连接字符串?在上面的例子中,它是存储在cfg.DocumentDatabase.BlobStorageServer中的设置

谢谢

c# azure azure-webjobs azure-webjobssdk
4个回答
2
投票

官方样本可在WebJob Github获得

在函数中,您可以传递appsettings.json中使用的连接字符串键名

例如:

public void ProcessBlob([BlobTrigger("blobPath", Connection = "AzureWebJobsBlobConnection")] string blob)

“AzureWebJobsBlobConnection”在appsettings.json中配置如下:{ "Logging": { ... }, "AzureWebJobsBlobConnection": "...", }

并且不要忘记在program.cs中添加配置:

var builder = new HostBuilder()
            .ConfigureAppConfiguration((builderContext, cb) =>
            {
                IHostingEnvironment env = builderContext.HostingEnvironment;

                cb.AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);
            })
            .ConfigureWebJobs(b =>
            {
                b.AddAzureStorage(o => 
                {
                    o.MaxDequeueCount = 1;
                })
                .AddServiceBus(c =>
                {
                    c.MessageHandlerOptions.MaxConcurrentCalls = 1;
                });
            })
            .ConfigureLogging((webHostBuilder, loggingBuilder) =>
            {
                loggingBuilder.AddConsole();
                loggingBuilder.AddDebug();
            })
            .ConfigureServices((hb, sc) =>
            {
                string connectionString = hb.Configuration.GetConnectionString("DefaultConnection");

                sc.AddScoped<Functions, Functions>();
                ...
            });

        builder.RunConsoleAsync().GetAwaiter().GetResult();

1
投票

所以,在盯着webjob SDK的源代码后,我找到了一个kludge。好吧,我认为这是一个混乱。它工作,我现在可以使用新的3.0 SDK。

我在这里发布这个,主要是因为我担心没有其他方法可以使用我自己的配置文件。

如果这是错的,请告诉我,我将删除此答案。

所以我的代码现在看起来像这样:

    _wjHost = new HostBuilder().ConfigureWebJobs(b =>
    {
        b.AddAzureStorage(x =>
        {
            x.MaxPollingInterval = TimeSpan.FromSeconds(_pollSeconds);
        });
    }).ConfigureServices(s =>
    {
        s.AddSingleton(new StorageAccountProvider(new BlobStorageConfiguration(cfg.DocumentDatabase.BlobStorageServer)));
        s.AddSingleton<INameResolver, Support.BlobNameResolver>(_ => new Support.BlobNameResolver(_env));
        s.Configure<QueuesOptions>(o =>
        {
            o.MaxPollingInterval = TimeSpan.FromSeconds(_pollSeconds);
        });
    }).Build();

我添加的线是s.AddSingleton(new StorageAccountProvider(new BlobStorageConfiguration(cfg.DocumentDatabase.BlobStorageServer)));

webjobs SDK专门寻找名为Storage的密钥。所以我不得不实施IConfiguration并将其解决方案如下:

private sealed class BlobStorageConfiguration : IConfiguration
{
    private readonly string _bsConnString;
    public BlobStorageConfiguration(string connString)
    {
        _bsConnString = connString;
    }

    public string this[string key]
    {
        get => key == "Storage" ? _bsConnString : null;
        set { }
    }

    public IEnumerable<IConfigurationSection> GetChildren() => null;
    public IChangeToken GetReloadToken() => null;
    public IConfigurationSection GetSection(string key) => null;
}

现在触发器正好点火了。不漂亮。但是有关于新IHost方法的ZERO文档。


0
投票

在WebSDK 3中,作业是通过appsettings.json文件配置的,就像它对ASP.NET Core一样。

你可以看到一个例子on the official Github repo,但我还将在下面添加一个更完整的例子。

appsettings.development.json中,通过ConnectionStrings["AzureWebJobsStorage"]属性将其配置为使用本地存储:

{
  "ConnectionStrings": {
    "AzureWebJobsDashboard": "UseDevelopmentStorage=true",
    "AzureWebJobsStorage": "UseDevelopmentStorage=true"
  }
}

appsettings.json中,将其配置为prod:

{
  "ConnectionStrings": {
    "AzureWebJobsDashboard": "DefaultEndpointsProtocol=https;AccountName=name;AccountKey=key",
    "AzureWebJobsStorage": "DefaultEndpointsProtocol=https;AccountName=name;AccountKey=key"
  }
}

我的完整Program.cs看起来像这样(带注释):

public class Program
{
    public static async Task Main(string[] args)
    {
        var builder = new HostBuilder();

        // allows us to read the configuration file from current directory
        // (remember to copy those files to the OutputDirectory in VS)
        builder.UseContentRoot(Directory.GetCurrentDirectory());

        // configure things like batch size, service bus, etc..
        builder.ConfigureWebJobs(b =>
        {
            b
            .AddAzureStorageCoreServices()
            .AddAzureStorage(options =>
            {
                options.BatchSize = 1;
                options.MaxDequeueCount = 1;
            })
            ;
        });

        // this step allows the env variable to be read BEFORE the rest of the configuration
        // => this is useful to configure the hosting environment in debug, by setting the 
        // ENVIRONMENT variable in VS
        builder.ConfigureHostConfiguration(config =>
        {
            config.AddEnvironmentVariables();
        });

        // reads the configuration from json file
        builder.ConfigureAppConfiguration((context, config) =>
        {
            var env = context.HostingEnvironment;

            // Adding command line as a configuration source
            config
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true, reloadOnChange: true);

            config.AddEnvironmentVariables();
            if (args != null)
                config.AddCommandLine(args);
        });

        // configure logging (you can use the config here, via context.Configuration)
        builder.ConfigureLogging((context, loggingBuilder) =>
        {
            loggingBuilder.AddConfiguration(context.Configuration.GetSection("Logging"));
            loggingBuilder.AddConsole();

            // If this key exists in any config, use it to enable App Insights
            var appInsightsKey = context.Configuration["APPINSIGHTS_INSTRUMENTATIONKEY"];
            if (!string.IsNullOrEmpty(appInsightsKey))
            {
                loggingBuilder.AddApplicationInsights(o => o.InstrumentationKey = appInsightsKey);
            }
        });

        // inject dependencies via DI
        builder.ConfigureServices((context, services) =>
        {
            services.AddSingleton<INameResolver>(new QueueNameResolver("test"));

            services.AddDbContextPool<DbContext>(options =>
                options.UseSqlServer(context.Configuration.GetConnectionString("DbContext"))
            );
        });

        // finalize host config
        builder.UseConsoleLifetime();

        var host = builder.Build();
        using (host)
        {
            await host.RunAsync();
        }
    }
}

0
投票

万一有人遇到与使用QueueTrigger时解析队列名称相同的情况:

您必须使用“Microsoft.Extensions.DependencyInjection”包才能使用以下代码。

static void Main(string[] args)
    {
        var environment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
        Console.WriteLine($"Current Environment : {(string.IsNullOrEmpty(environment) ? "Development" : environment)}");

        var config = new ConfigurationBuilder()
            .SetBasePath(Directory.GetCurrentDirectory())
            .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true)
            .AddJsonFile($"appsettings.{environment}.json", optional: true, reloadOnChange: true)
            .AddEnvironmentVariables()
            .Build();

        var builder = new HostBuilder();
        builder.UseEnvironment("Development");
        builder.ConfigureLogging((context, b) =>
        {
            b.AddConsole();
        });

        builder.ConfigureWebJobs(b =>
        {

            b.AddAzureStorageCoreServices();
            b.AddAzureStorage();
            // b.AddTimers();

            b.AddServiceBus(c =>
            {
                c.ConnectionString = "[Your Connection String]";
            });
        }).ConfigureServices((context, services)=>
        {
            services.AddSingleton<INameResolver>(new QueueNameResolver(config));
        });

        var host = builder.Build();


        using (host)
        {
            host.Run();
        }
    }

public class QueueNameResolver : INameResolver
{
    private readonly IConfiguration _configuration;
    public QueueNameResolver(IConfiguration configuration)
    {
        _configuration = configuration;
    }
    public string Resolve(string name)
    {
        return _configuration[$"AppSettings:{name}"];
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.