diff --git a/eng/.docsettings.yml b/eng/.docsettings.yml
index 4165f16ae065..50cd77e7f7c4 100644
--- a/eng/.docsettings.yml
+++ b/eng/.docsettings.yml
@@ -168,6 +168,7 @@ known_content_issues:
- ['sdk/core/Microsoft.Azure.Core.NewtonsoftJson/README.md', '#15423']
- ['sdk/core/Microsoft.Azure.Core.Spatial/README.md', '#15423']
- ['sdk/core/Microsoft.Azure.Core.Spatial.NewtonsoftJson/README.md', '#15423']
+ - ['sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/README.md', '#15423']
# .net climbs upwards. placing these to prevent assigning readmes to the wrong project
package_indexing_exclusion_list:
diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/CHANGELOG.md b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/CHANGELOG.md
new file mode 100644
index 000000000000..0620c48c0f79
--- /dev/null
+++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/CHANGELOG.md
@@ -0,0 +1,5 @@
+# Release History
+
+## 5.0.0-beta.1 (Unreleased)
+
+- The initial release of Microsoft.Azure.WebJobs.Extensions.ServiceBus 5.0.0
diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/Directory.Build.props b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/Directory.Build.props
new file mode 100644
index 000000000000..805ca8beaf23
--- /dev/null
+++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/Directory.Build.props
@@ -0,0 +1,7 @@
+
+
+ true
+
+
+
+
diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/Microsoft.Azure.WebJobs.Extensions.ServiceBus.sln b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/Microsoft.Azure.WebJobs.Extensions.ServiceBus.sln
new file mode 100644
index 000000000000..62ef554f02dd
--- /dev/null
+++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/Microsoft.Azure.WebJobs.Extensions.ServiceBus.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.30804.86
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.ServiceBus", "src\Microsoft.Azure.WebJobs.Extensions.ServiceBus.csproj", "{2AC0E7B8-38C9-4B94-87B2-2FDDFA278464}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Microsoft.Azure.WebJobs.Extensions.ServiceBus.Tests", "tests\Microsoft.Azure.WebJobs.Extensions.ServiceBus.Tests.csproj", "{564B3907-57C9-456A-9C7B-C6D876B24479}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2AC0E7B8-38C9-4B94-87B2-2FDDFA278464}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2AC0E7B8-38C9-4B94-87B2-2FDDFA278464}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2AC0E7B8-38C9-4B94-87B2-2FDDFA278464}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2AC0E7B8-38C9-4B94-87B2-2FDDFA278464}.Release|Any CPU.Build.0 = Release|Any CPU
+ {564B3907-57C9-456A-9C7B-C6D876B24479}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {564B3907-57C9-456A-9C7B-C6D876B24479}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {564B3907-57C9-456A-9C7B-C6D876B24479}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {564B3907-57C9-456A-9C7B-C6D876B24479}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {371BFA14-0980-4A43-A18A-CA1C1A9CB784}
+ EndGlobalSection
+EndGlobal
diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/README.md b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/README.md
new file mode 100644
index 000000000000..bfeb94ebe89b
--- /dev/null
+++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/README.md
@@ -0,0 +1,56 @@
+# Azure WebJobs Service Bus client library for .NET
+
+This extension provides functionality for accessing Azure Service Bus from an Azure Function.
+
+## Getting started
+
+### Install the package
+
+### Prerequisites
+
+
+### Authenticate the Client
+
+#### Managed identity authentication
+
+
+## Key concepts
+
+
+## Examples
+
+
+## Troubleshooting
+
+
+## Next steps
+
+
+## Contributing
+
+See our [CONTRIBUTING.md][contrib] for details on building,
+testing, and contributing to this library.
+
+This project welcomes contributions and suggestions. Most contributions require
+you to agree to a Contributor License Agreement (CLA) declaring that you have
+the right to, and actually do, grant us the rights to use your contribution. For
+details, visit [cla.microsoft.com][cla].
+
+This project has adopted the [Microsoft Open Source Code of Conduct][coc].
+For more information see the [Code of Conduct FAQ][coc_faq]
+or contact [opencode@microsoft.com][coc_contact] with any
+additional questions or comments.
+
+
+
+
+[source]: https://github.com/Azure/azure-sdk-for-net/tree/master/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src
+[package]: https://www.nuget.org/packages/Microsoft.Azure.WebJobs.Extensions.ServiceBus/
+[docs]: https://docs.microsoft.com/dotnet/api/Microsoft.Azure.WebJobs.Extensions.ServiceBus
+[nuget]: https://www.nuget.org/
+
+[contrib]: https://github.com/Azure/azure-sdk-for-net/tree/master/CONTRIBUTING.md
+[cla]: https://cla.microsoft.com
+[coc]: https://opensource.microsoft.com/codeofconduct/
+[coc_faq]: https://opensource.microsoft.com/codeofconduct/faq/
+[coc_contact]: mailto:opencode@microsoft.com
diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/AsyncCollectorArgumentBindingProvider.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/AsyncCollectorArgumentBindingProvider.cs
new file mode 100644
index 000000000000..36dea113e955
--- /dev/null
+++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/AsyncCollectorArgumentBindingProvider.cs
@@ -0,0 +1,83 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+using System;
+using System.Diagnostics;
+using System.Reflection;
+using System.Threading.Tasks;
+using Microsoft.Azure.ServiceBus;
+using Microsoft.Azure.WebJobs.Host.Bindings;
+using Microsoft.Azure.WebJobs.Host.Converters;
+
+namespace Microsoft.Azure.WebJobs.ServiceBus.Bindings
+{
+ internal class AsyncCollectorArgumentBindingProvider : IQueueArgumentBindingProvider
+ {
+ public IArgumentBinding TryCreate(ParameterInfo parameter)
+ {
+ Type parameterType = parameter.ParameterType;
+
+ if (!parameterType.IsGenericType)
+ {
+ return null;
+ }
+
+ Type genericTypeDefinition = parameterType.GetGenericTypeDefinition();
+
+ if (genericTypeDefinition != typeof(IAsyncCollector<>))
+ {
+ return null;
+ }
+
+ Type itemType = parameterType.GetGenericArguments()[0];
+ return CreateBinding(itemType);
+ }
+
+ private static IArgumentBinding CreateBinding(Type itemType)
+ {
+ MethodInfo method = typeof(AsyncCollectorArgumentBindingProvider).GetMethod("CreateBindingGeneric",
+ BindingFlags.NonPublic | BindingFlags.Static);
+ Debug.Assert(method != null);
+ MethodInfo genericMethod = method.MakeGenericMethod(itemType);
+ Debug.Assert(genericMethod != null);
+ Func> lambda =
+ (Func>)Delegate.CreateDelegate(
+ typeof(Func>), genericMethod);
+ return lambda.Invoke();
+ }
+
+ private static IArgumentBinding CreateBindingGeneric()
+ {
+ return new AsyncCollectorArgumentBinding(MessageConverterFactory.Create());
+ }
+
+ private class AsyncCollectorArgumentBinding : IArgumentBinding
+ {
+ private readonly IConverter _converter;
+
+ public AsyncCollectorArgumentBinding(IConverter converter)
+ {
+ _converter = converter;
+ }
+
+ public Type ValueType
+ {
+ get { return typeof(IAsyncCollector); }
+ }
+
+ public Task BindAsync(ServiceBusEntity value, ValueBindingContext context)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ IAsyncCollector collector = new MessageSenderAsyncCollector(value, _converter,
+ context.FunctionInstanceId);
+ IValueProvider provider = new CollectorValueProvider(value, collector, typeof(IAsyncCollector));
+
+ return Task.FromResult(provider);
+ }
+ }
+ }
+}
diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/BindableServiceBusPath.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/BindableServiceBusPath.cs
new file mode 100644
index 000000000000..311502f69a0b
--- /dev/null
+++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/BindableServiceBusPath.cs
@@ -0,0 +1,41 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
+using Microsoft.Azure.WebJobs.Host.Bindings;
+using Microsoft.Azure.WebJobs.Host.Bindings.Path;
+
+namespace Microsoft.Azure.WebJobs.ServiceBus.Bindings
+{
+ ///
+ /// Utility class with factory method to create an instance of a strategy class implementing interface.
+ ///
+ internal static class BindableServiceBusPath
+ {
+ ///
+ /// A factory method detecting parameters in supplied queue or topic name pattern and creating
+ /// an instance of relevant strategy class implementing .
+ ///
+ /// Service Bus queue or topic name pattern containing optional binding parameters.
+ /// An object implementing
+ public static IBindableServiceBusPath Create(string queueOrTopicNamePattern)
+ {
+ if (queueOrTopicNamePattern == null)
+ {
+ throw new ArgumentNullException(nameof(queueOrTopicNamePattern));
+ }
+
+ BindingTemplate template = BindingTemplate.FromString(queueOrTopicNamePattern);
+
+ if (template.ParameterNames.Any())
+ {
+ return new ParameterizedServiceBusPath(template);
+ }
+
+ return new BoundServiceBusPath(queueOrTopicNamePattern);
+ }
+ }
+}
diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/BoundServiceBusPath.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/BoundServiceBusPath.cs
new file mode 100644
index 000000000000..56dfc28ea283
--- /dev/null
+++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/BoundServiceBusPath.cs
@@ -0,0 +1,42 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+using System.Collections.Generic;
+using System.Linq;
+
+namespace Microsoft.Azure.WebJobs.ServiceBus.Bindings
+{
+ ///
+ /// Bindable queue or topic path strategy implementation for "degenerate" bindable patterns,
+ /// i.e. containing no parameters.
+ ///
+ internal class BoundServiceBusPath : IBindableServiceBusPath
+ {
+ private readonly string _queueOrTopicNamePattern;
+
+ public BoundServiceBusPath(string queueOrTopicNamePattern)
+ {
+ _queueOrTopicNamePattern = queueOrTopicNamePattern;
+ }
+
+ public string QueueOrTopicNamePattern
+ {
+ get { return _queueOrTopicNamePattern; }
+ }
+
+ public bool IsBound
+ {
+ get { return true; }
+ }
+
+ public IEnumerable ParameterNames
+ {
+ get { return Enumerable.Empty(); }
+ }
+
+ public string Bind(IReadOnlyDictionary bindingData)
+ {
+ return QueueOrTopicNamePattern;
+ }
+ }
+}
diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/ByteArrayArgumentBindingProvider.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/ByteArrayArgumentBindingProvider.cs
new file mode 100644
index 000000000000..dc5b25c96521
--- /dev/null
+++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/ByteArrayArgumentBindingProvider.cs
@@ -0,0 +1,64 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+using System;
+using System.Reflection;
+using System.Threading.Tasks;
+using Microsoft.Azure.WebJobs.Host.Bindings;
+
+namespace Microsoft.Azure.WebJobs.ServiceBus.Bindings
+{
+ internal class ByteArrayArgumentBindingProvider : IQueueArgumentBindingProvider
+ {
+ public IArgumentBinding TryCreate(ParameterInfo parameter)
+ {
+ if (!parameter.IsOut || parameter.ParameterType != typeof(byte[]).MakeByRefType())
+ {
+ return null;
+ }
+
+ return new ByteArrayArgumentBinding();
+ }
+
+ private class ByteArrayArgumentBinding : IArgumentBinding
+ {
+ public Type ValueType
+ {
+ get { return typeof(byte[]); }
+ }
+
+ ///
+ /// The out byte array parameter is processed as follows:
+ ///
+ /// -
+ ///
+ /// If the value is , no message will be sent.
+ ///
+ ///
+ /// -
+ ///
+ /// If the value is an empty byte array, a message with empty content will be sent.
+ ///
+ ///
+ /// -
+ ///
+ /// If the value is a non-empty byte array, a message with that content will be sent.
+ ///
+ ///
+ ///
+ ///
+ public Task BindAsync(ServiceBusEntity value, ValueBindingContext context)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ IValueProvider provider = new NonNullConverterValueBinder(value,
+ new ByteArrayToBrokeredMessageConverter(), context.FunctionInstanceId);
+
+ return Task.FromResult(provider);
+ }
+ }
+ }
+}
diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/ByteArrayToBrokeredMessageConverter.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/ByteArrayToBrokeredMessageConverter.cs
new file mode 100644
index 000000000000..205edcff8ab4
--- /dev/null
+++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/ByteArrayToBrokeredMessageConverter.cs
@@ -0,0 +1,26 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+using System;
+using System.Diagnostics.CodeAnalysis;
+using Microsoft.Azure.ServiceBus;
+
+namespace Microsoft.Azure.WebJobs.ServiceBus.Bindings
+{
+ internal class ByteArrayToBrokeredMessageConverter : IConverter
+ {
+ [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")]
+ public Message Convert(byte[] input)
+ {
+ if (input == null)
+ {
+ throw new InvalidOperationException("A brokered message cannot contain a null byte array instance.");
+ }
+
+ return new Message(input)
+ {
+ ContentType = ContentTypes.ApplicationOctetStream
+ };
+ }
+ }
+}
diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/CollectorArgumentBindingProvider.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/CollectorArgumentBindingProvider.cs
new file mode 100644
index 000000000000..05f3da39235f
--- /dev/null
+++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/CollectorArgumentBindingProvider.cs
@@ -0,0 +1,83 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+using System;
+using System.Diagnostics;
+using System.Reflection;
+using System.Threading.Tasks;
+using Microsoft.Azure.WebJobs.Host.Bindings;
+using Microsoft.Azure.WebJobs.Host.Converters;
+using Microsoft.Azure.ServiceBus;
+
+namespace Microsoft.Azure.WebJobs.ServiceBus.Bindings
+{
+ internal class CollectorArgumentBindingProvider : IQueueArgumentBindingProvider
+ {
+ public IArgumentBinding TryCreate(ParameterInfo parameter)
+ {
+ Type parameterType = parameter.ParameterType;
+
+ if (!parameterType.IsGenericType)
+ {
+ return null;
+ }
+
+ Type genericTypeDefinition = parameterType.GetGenericTypeDefinition();
+
+ if (genericTypeDefinition != typeof(ICollector<>))
+ {
+ return null;
+ }
+
+ Type itemType = parameterType.GetGenericArguments()[0];
+ return CreateBinding(itemType);
+ }
+
+ private static IArgumentBinding CreateBinding(Type itemType)
+ {
+ MethodInfo method = typeof(CollectorArgumentBindingProvider).GetMethod("CreateBindingGeneric",
+ BindingFlags.NonPublic | BindingFlags.Static);
+ Debug.Assert(method != null);
+ MethodInfo genericMethod = method.MakeGenericMethod(itemType);
+ Debug.Assert(genericMethod != null);
+ Func> lambda =
+ (Func>)Delegate.CreateDelegate(
+ typeof(Func>), genericMethod);
+ return lambda.Invoke();
+ }
+
+ private static IArgumentBinding CreateBindingGeneric()
+ {
+ return new CollectorArgumentBinding(MessageConverterFactory.Create());
+ }
+
+ private class CollectorArgumentBinding : IArgumentBinding
+ {
+ private readonly IConverter _converter;
+
+ public CollectorArgumentBinding(IConverter converter)
+ {
+ _converter = converter;
+ }
+
+ public Type ValueType
+ {
+ get { return typeof(ICollector); }
+ }
+
+ public Task BindAsync(ServiceBusEntity value, ValueBindingContext context)
+ {
+ if (context == null)
+ {
+ throw new ArgumentNullException(nameof(context));
+ }
+
+ ICollector collector = new MessageSenderCollector(value, _converter,
+ context.FunctionInstanceId);
+ IValueProvider provider = new CollectorValueProvider(value, collector, typeof(ICollector));
+
+ return Task.FromResult(provider);
+ }
+ }
+ }
+}
diff --git a/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/CollectorValueProvider.cs b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/CollectorValueProvider.cs
new file mode 100644
index 000000000000..9d6beee23ff9
--- /dev/null
+++ b/sdk/servicebus/Microsoft.Azure.WebJobs.Extensions.ServiceBus/src/Bindings/CollectorValueProvider.cs
@@ -0,0 +1,43 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the MIT License. See License.txt in the project root for license information.
+
+using System;
+using System.Threading.Tasks;
+using Microsoft.Azure.WebJobs.Host.Bindings;
+
+namespace Microsoft.Azure.WebJobs.ServiceBus.Bindings
+{
+ internal class CollectorValueProvider : IValueProvider
+ {
+ private readonly ServiceBusEntity _entity;
+ private readonly object _value;
+ private readonly Type _valueType;
+
+ public CollectorValueProvider(ServiceBusEntity entity, object value, Type valueType)
+ {
+ if (value != null && !valueType.IsAssignableFrom(value.GetType()))
+ {
+ throw new InvalidOperationException("value is not of the correct type.");
+ }
+
+ _entity = entity;
+ _value = value;
+ _valueType = valueType;
+ }
+
+ public Type Type
+ {
+ get { return _valueType; }
+ }
+
+ public Task