Someone out there must have run into this already...
I created a WebApi solution with swagger implemented, full documentation, the whole 9 yards!
When I run my web api solution, see the swagger output (and I've tested the endpoints, all working fine)
I can see the swagger definition: https://localhost:5001/swagger/v1/swagger.json
Now, I want to consume this Api as a connected service on my web app.
So following every single tutorial online:
I go to my webapp
right click on Connected Services
Add Connected Service
Add Service Reference > OpenApi > add Url, namespace & class name
That generates a partial class in my solution (MyTestApiClient)
public parial class MyTestApiClient
{
// auto generated code
}
Next step, inject the service in Startup.cs
services.AddTransient(x =>
{
var client = new MyTestApiClient("https://localhost:5001", new HttpClient());
return client;
});
Then, inject the class into some class where it's consumed and this all works
public class TestService
{
private readonly MyTestApiClient _client; // this is class, not an interface -> my problem
public TestService(MyTestApiClient client)
{
_client = client;
}
public async Task<int> GetCountAsync()
{
return _client.GetCountAsync();
}
}
So everything up to here works. BUT, this generated OpenApi client doesn't have an interface which sucks for the purposes of DI and Unit Testing.
I got around this by creating a local interface IMyTestApiClient, added to the generated class (MyTestApiClient). I only have 1 endpoint in my WebApi so have to declare that on my interface.
public parial class MyTestApiClient : IMyTestApiClient
{
// auto generated code
}
public interface IMyTestApiClient
{
// implemented in generated MyTestApiClient class
Task<int> GetCountAsync();
}
services.AddTransient<IMyTestApiClient, MyTestApiClient>(x =>
{
IMyTestApiClient client = new MyTestApiClient("https://localhost:5001", new HttpClient());
return client;
});
public class TestService
{
private readonly IMyTestApiClient _client; // now injecting local interface instead of the generated class - great success
public TestService(IMyTestApiClient client)
{
_client = client;
}
public async Task<int> GetCountAsync()
{
return _client.GetCountAsync();
}
}
But this is a bad approach because it makes me manually create an interface and explicitly declare the methods I want to consume. Furthermore, every time my Api gets updated, I will have to tweak my local interface.
So question time:
How can I add an OpenApi Service Reference that automagically also generates an interface as well?
Thanks in advance for any help getting to a viable solution.
You may have already found the answer but I had the same issue and managed to resolve it by adding /GenerateClientInterfaces:true in the Options section for the OpenAPI reference in my .csproj:
<OpenApiReference Include="api.json" CodeGenerator="NSwagCSharp" Namespace="MyNamespace" ClassName="MyClassName">
<SourceUri>https://localhost:7040/swagger/v1/swagger.json</SourceUri>
<OutputPath>MyClient.cs</OutputPath>
<Options>/GenerateClientInterfaces:true</Options>
</OpenApiReference>
I have some class libraries that I use in my ASP.NET Web API app that handle all my backend stuff e.g. CRUD operations to multiple databases like Azure SQL Database, Cosmos DB, etc.
I don't want to re-invent the wheel and able to use them in a new Azure Functions that I'm creating in Visual Studio 2017. All my repository methods use an interface. So, how will I implement dependency injection in my new Azure function?
I'm not seeing any support for DI but I'm a bit confused. It appears Azure Functions are based on the same SDK as WebJobs and I think last year Microsoft had started supporting DI in WebJobs - I know for sure because I implemented it using Ninject.
Is there way around this so that I can use my existing libraries in my new Azure Functions project?
I see these two techniques in addition to the service locator (anti)pattern. I asked the Azure Functions team for their comments as well.
https://blog.wille-zone.de/post/azure-functions-dependency-injection/
https://blog.wille-zone.de/post/azure-functions-proper-dependency-injection/
There is an open feature request on the GitHub pages for Azure Functions concerning this matter.
However, the way I'm approaching this is using some kind of 'wrapper' entry point, resolve this using the service locator and and start the function from there.
This looks a bit like this (simplified)
var builder = new ContainerBuilder();
//register my types
var container = builder.Build();
using(var scope = container.BeginLifetimeScope())
{
var functionLogic = scope.Resolve<IMyFunctionLogic>();
functionLogic.Execute();
}
This is a bit hacky of course, but it's the best there is until there is at the moment (to my knowledge).
I've seen the willie-zone blog mentioned a lot when it comes to this topic, but you don't need to go that route to use DI with Azure functions.
If you are using Version2 you can make your Azure functions non-static. Then you can add a public constructor for injecting your dependencies. The next step is to add an IWebJobsStartup class. In your startup class you will be able to register your services like you would for any other .Net Core project.
I have a public repo that is using this approach here: https://github.com/jedi91/MovieSearch/tree/master/MovieSearch
Here is a direct link to the startup class: https://github.com/jedi91/MovieSearch/blob/master/MovieSearch/Startup.cs
And here is the function: https://github.com/jedi91/MovieSearch/blob/master/MovieSearch/Functions/Search.cs
Hope this approach helps. If you are wanting to keep your Azure Functions static then the willie-zone approach should work, but I really like this approach and it doesn't require any third party libraries.
One thing to note is the Directory.Build.target file. This file will copy your extensions over in the host file so that DI will work once the function is deployed to Azure. Running the function locally does not require this file.
Azure Functions Depdendency Injection was announced at MSBuild 2019. Here's an example on how to do it:
[assembly: FunctionsStartup(typeof(MyNamespace.Startup))]
namespace MyNamespace
{
public class Startup : FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddHttpClient();
builder.Services.AddSingleton((s) => {
return new CosmosClient(Environment.GetEnvironmentVariable("COSMOSDB_CONNECTIONSTRING"));
});
builder.Services.AddSingleton<ILoggerProvider, MyLoggerProvider>();
}
}
}
GitHub Example
Documentation
As stated above, it was just announced at Build 2019. It can now be setup almost exactly like you would in an ASP .Net Core app.
Microsoft Documentation
Short Blog I Wrote
Actually there is a much nicer and simpler way provided out of the box by Microsoft. It is a bit hard to find though. You simply create a start up class and add all required services here, and then you can use constructor injection like in regular web apps and web apis.
This is all you need to do.
First I create my start up class, I call mine Startup.cs to be consistent with Razor web apps, although this is for Azure Functions, but still it's the Microsoft way.
using System;
using com.paypal;
using dk.commentor.bl.command;
using dk.commentor.logger;
using dk.commentor.sl;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using org.openerp;
[assembly:Microsoft.Azure.WebJobs.Hosting.WebJobsStartup(typeof(dk.commentor.starterproject.api.Startup))]
namespace dk.commentor.starterproject.api
{
public class Startup : IWebJobsStartup
{
public void Configure(IWebJobsBuilder builder)
{
builder.Services.AddSingleton<ILogger, CommentorLogger>();
builder.Services.AddSingleton<IPaymentService, PayPalService>();
builder.Services.AddSingleton<IOrderService, OpenERPService>();
builder.Services.AddSingleton<ProcessOrderCommand>();
Console.WriteLine("Host started!");
}
}
}
Next I change the method call in the function from static to non-static, and I add a constructor to the class (which is now also non-static). In this constructor I simply add the services I require as constructor parameters.
using System;
using System.IO;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Extensions.Http;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json;
using dk.commentor.bl.command;
namespace dk.commentor.starterproject.api
{
public class ProcessOrder
{
private ProcessOrderCommand processOrderCommand;
public ProcessOrder(ProcessOrderCommand processOrderCommand) {
this.processOrderCommand = processOrderCommand;
}
[FunctionName("ProcessOrder")]
public async Task<IActionResult> Run([HttpTrigger(AuthorizationLevel.Function, "post", Route = null)] HttpRequest req, ILogger log)
{
log.LogInformation("C# HTTP trigger ProcessOrder called!");
log.LogInformation(System.Environment.StackTrace);
string jsonRequestData = await new StreamReader(req.Body).ReadToEndAsync();
dynamic requestData = JsonConvert.DeserializeObject(jsonRequestData);
if(requestData?.orderId != null)
return (ActionResult)new OkObjectResult($"Processing order with id {requestData.orderId}");
else
return new BadRequestObjectResult("Please pass an orderId in the request body");
}
}
}
Hopes this helps.
I would like to add my 2 cents to it. I used the technique that it's used by Host injecting ILogger. If you look at the Startup project I created GenericBindingProvider that implements IBindingProvider. Then for each type I want to be injected I register it as follow:
builder.Services.AddTransient<IWelcomeService, WelcomeService>();
builder.Services.AddSingleton<IBindingProvider, GenericBindingProvider<IWelcomeService>>();
The downside is that you need to register the type you want to be injected into the function twice.
Sample code:
Azure Functions V2 Dependency Injection sample
I have been using SimpleInjector perfectly fine in Azure Functions. Just create a class (let's call it IoCConfig) that has the registrations and make a static instance of that class in function class so that each instance will use the existing instance.
public interface IIoCConfig
{
T GetInstance<T>() where T : class;
}
public class IoCConfig : IIoCConfig
{
internal Container Container;
public IoCConfig(ExecutionContext executionContext, ILogger logger)
{
var configurationRoot = new ConfigurationBuilder()
.SetBasePath(executionContext.FunctionAppDirectory)
.AddJsonFile("local.settings.json", optional: true, reloadOnChange: true)
.AddEnvironmentVariables()
.Build();
Container = new Container();
Configure(configurationRoot, logger);
}
public IoCConfig(IConfigurationRoot configurationRoot, ILogger logger)
{
Container = new Container();
Configure(configurationRoot, logger);
}
private void Configure(IConfigurationRoot configurationRoot, ILogger logger)
{
Container.RegisterInstance(typeof(IConfigurationRoot), configurationRoot);
Container.Register<ISomeType, SomeType>();
}
public T GetInstance<T>() where T : class
{
return Container.GetInstance<T>();
}
}
Then in root:
public static class SomeFunction
{
public static IIoCConfig IoCConfig;
[FunctionName("SomeFunction")]
public static async Task Run(
[ServiceBusTrigger("some-topic", "%SUBSCRIPTION_NAME%", Connection = "AZURE_SERVICEBUS_CONNECTIONSTRING")]
SomeEvent msg,
ILogger log,
ExecutionContext executionContext)
{
Ensure.That(msg).IsNotNull();
if (IoCConfig == null)
{
IoCConfig = new IoCConfig(executionContext, log);
}
var someType = IoCConfig.GetInstance<ISomeType>();
await someType.Handle(msg);
}
}
AzureFunctions.Autofac is very easy to use.
Just add a config file:
public class DIConfig
{
public DIConfig(string functionName)
{
DependencyInjection.Initialize(builder =>
{
builder.RegisterType<Sample>().As<ISample>();
...
}, functionName);
}
}
Add the DependencyInjectionConfig attribute then inject:
[DependencyInjectionConfig(typeof(DIConfig))]
public class MyFunction
{
[FunctionName("MyFunction")]
public static HttpResponseMessage Run([HttpTrigger(AuthorizationLevel.Function, "get", Route = null)]HttpRequestMessage request,
TraceWriter log,
[Inject]ISample sample)
{
https://github.com/introtocomputerscience/azure-function-autofac-dependency-injection
I think this is a better solution:
https://github.com/junalmeida/autofac-azurefunctions
https://www.nuget.org/packages/Autofac.Extensions.DependencyInjection.AzureFunctions
Install the NuGet in your project and then make a Startup.cs and put this in it:
[assembly: FunctionsStartup(typeof(Startup))]
public class Startup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder
.UseAppSettings() // this is optional, this will bind IConfiguration in the container.
.UseAutofacServiceProviderFactory(ConfigureContainer);
}
private void ConfigureContainer(ContainerBuilder builder)
{
// do DI registration against Autofac like normal! (builder is just the normal ContainerBuilder from Autofac)
}
...
Then in your function code you can do normal constructor injection via DI:
public class Function1 : Disposable
{
public Function1(IService1 service1, ILogger logger)
{
// logger and service1 injected via autofac like normal
// ...
}
[FunctionName(nameof(Function1))]
public async Task Run([QueueTrigger("myqueue-items", Connection = "AzureWebJobsStorage")]string myQueueItem)
{
//...
Support for Dependency injection begins with Azure Functions 2.x which means Dependency Injection in Azure function can now leverage .NET Core Dependency Injection features.
Before you can use dependency injection, you must install the following NuGet packages:
Microsoft.Azure.Functions.Extensions
Microsoft.NET.Sdk.Functions
Having Dependency Injection eases things like DBContext, Http client usage (Httpclienfactory), Iloggerfactory, cache support etc.
Firstly, update the Startup class as shown below
namespace DemoApp
{
public class Startup: FunctionsStartup
{
public override void Configure(IFunctionsHostBuilder builder)
{
builder.Services.AddScoped<IHelloWorld, HelloWorld>();
// Registering Serilog provider
var logger = new LoggerConfiguration()
.WriteTo.Console()
.CreateLogger();
builder.Services.AddLogging(lb => lb.AddSerilog(logger));
//Reading configuration section can be added here etc.
}
}
}
Secondly, Removal of Static keyword in Function class and method level
public class DemoFunction
{
private readonly IHelloWorld _helloWorld;
public DemoFunction(IHelloWorld helloWorld)
{
_helloWorld = helloWorld;
}
[FunctionName("HttpDemoFunction")]
public async Task<IActionResult> Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = null)] HttpRequest req,
ILogger log)
{
log.LogInformation("C# HTTP trigger function processed a request.");
}
If we look into above e.g. IHelloWorld is injected using .NET Core DI
**Note:**In-spite of having latest version of Azure function v3 for Dependency Injection to enable few steps are manual as shown above
Sample code on github can be found here
may be I got it all wrong but in all the companies I have worked we never added a reference to the Dal in the UI layer (winforms-Web)
I am new to web but a seasoned winform-wcf developer,however I am struggling with the concept of having the dal being referenced in the UI.
In a big team with no proper supervision is a recipe for disaster.
Why not have 2 composition roots
1)WebUI just services classes (not wcf) when using wcf composition root is in there
2)within the services that we inject there the repository.
Am i missing the obvious?
thanks
UPDATED
In all the samples I see they all use DI (Unity-Autofac-Nject etc..) and they wire up the repository via interface,which also requires the concrete class,hence the reference to the DAL.Can this be done in the service layer?
There's a way to inject dependencies without referencing data access layer from the UI. You have to add a transversal Utils or Helpers project that will resolve all dependencies across the project.
In this explanation I'll use Unity for DI. I'll walk your through it in a couple of steps:
First, create an Utils project. This project will be transversal to all the layers. Add this static class with an extension method for IUnityContainer:
// This class will resolve all dependencies across the project
public static class DependencyResolver
{
// This method will resolve all dependencies
public static void ResolveDependencies(this IUnityContainer container)
{
container.ResolveBusinessLayerDependencies();
container.ResolveDataAccessLayerDependencies();
}
}
This will force you to create both methods: ResolveBusinessLayerDependencies and ResolveDataAccessLayerDependencies in the container.
Second, you should go to your business logic project (here, you should be able to access the interfaces and implementations of this layer). Add a new static class like this:
public static class DependencyResolver
{
public static void ResolveBusinessLayerDependencies(this IUnityContainer container)
{
container.RegisterType<IBusinessLayerClass, BusinessLayerClass>();
}
}
Do the same for your data access project:
public static class DependencyResolver
{
public static void ResolveDataAccessLayerDependencies(this IUnityContainer container)
{
container.RegisterType<IDataAccessLayerClass, DataAccessLayerClass>();
}
}
Now in the UnityConfig.cs, the method RegisterTypes would be something like:
public static void RegisterTypes(IUnityContainer container)
{
container.ResolveDependencies();
}
This is one way I've find useful to use DI without referencing all layers from the main project
We are using classes inheriting from Registry to configure our StructureMap container in our ASP.NET MVC 4 application startup.
Some excerpt from one of the registry-classes:
For<ISomeInterface>().HybridHttpOrThreadLocalScoped().Use<SomeImplementation>();
We would like use different instances of our interfaces depending on the context. (For example switching from database "online" mode to "maintenance" mode where everything is saved on filesystem; therefore using other interfaces (i.e. repositories) all over the place in our application)
For example by default it should use SomeImplementation but when passing some kind of querystring in the url (to name a simple "context" scenario) it should use SomeOtherImplementation.
How can this be achieved for multiple interfaces/types?
Should we use named instances for this? Like:
For<ISomeInterface>().HybridHttpOrThreadLocalScoped().Use<SomeOtherImplementation>().Named("other");
I read about StructureMap Profiles but i'm not sure if this is the right way to go.
Should we use profiles for this? Like i.e.:
Profile("other", profileExpression =>
{
For<ISomeInterface>().HybridHttpOrThreadLocalScoped().Use<SomeOtherImplementation>();
});
How can we switch different configurations on the fly?
ObjectFactory.Container.SetDefaultsToProfile("other");
This way? (At what stage in mvc "life-cycle" this can happen at the earliest?)
Can this be a temporary switch for just the current request or current users session?
Thanks in advance!
From my experience, runtime configuration like this is best achieved using an abstract factory that is responsible for creating your dependency during runtime.
This dependency can then be registered with StructureMap like so:
Your registry:
public class StorageRegistry : Registry
{
public StorageRegistry()
{
...
this.For<IDataStoreInstance>().Use(ctx => ctx.GetInstance<DataStoreAbstractFactory>().ConfigureStorage());
...
}
}
Now your DataStoreAbstractFactory is responsible for creating and configure the necessary storage instance based on your configuration. As DataStoreAbstractFactory is now registered with StructureMap you're able to inject the necessary dependencies into it for determining which storage method to use.
Implementation example:
public class DataStoreAbstractFactory
{
public DataStoreAbstractFactory()
{
// Dependencies to figure out data storage method can be injected here.
}
public IDataStoreInstance ConfigureStorage()
{
// This method can be used to return type of storage based on your configuration (ie: online or maintenance)
}
}
public interface IDataStoreInstance
{
void Save();
}
public class DatabaseStorage : IDataStoreInstance
{
public void Save()
{
// Implementation details of persisting data in a database
}
}
public class FileStorage : IDataStoreInstance
{
public void Save()
{
// Implementation details of persisting data in a file system
}
}
Usage:
Your controller/services or whatever are now completely unaware of what storage method they're using when accessing and persisting data.
public class UpdateController : Controller
{
public IDataStoreInstance StorageInstance { get; set; }
public UpdateController(IDataStoreInstance storageInstance)
{
StorageInstance = storageInstance;
}
[HttpPost]
public ActionResult Index()
{
...
this.StorageInstance.Save();
...
}
...
}
I am creating a website using Orchard CMS and I have an external .NET project written with Ninject for dependency injection which I would like to use together with a module within Orchard CMS. I know that Orchard uses Autofac for dependency injection and this is causing me problems since I never worked with DI before.
I have created an Autofac module, UserModule, which registers the a source, UserRegistrationSource, like this:
UserModule.cs
public class UserModule : Module
{
protected override void Load(ContainerBuilder builder)
{
builder.RegisterSource(new UserRegistrationSource());
}
}
UserRegistrationSource.cs
public class UserRegistrationSource : IRegistrationSource
{
public bool IsAdapterForIndividualComponents
{
get { return false; }
}
public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Func<Service, IEnumerable<IComponentRegistration>> registrationAccessor)
{
var serviceWithType = service as IServiceWithType;
if (serviceWithType == null)
yield break;
var serviceType = serviceWithType.ServiceType;
if (!serviceType.IsInterface || !typeof(IUserServices).IsAssignableFrom(serviceType) || serviceType != typeof(IUserServices))
yield break;
var registrationBuilder = // something...
yield return registrationBuilder.CreateRegistration();
}
}
UserServices.cs
public interface IUserServices : IDependency
{
void Add(string email, string password);
}
public class UserServices : IUserServices
{
private readonly EFMembershipManager _manager;
public UserServices(EFMembershipManager manager)
{
_manager = manager;
}
public void Add(string email, string password)
{
_manager.createUser(email, password);
}
}
EFMembershipManager.cs constructor
public EFMembershipManager(ServerRepository db,
ServerRepositoryMembershipProvider membershipProvider,
string testUsername,
string serverUsername)
{
...
}
EFMembershipManager is a class from the external project which uses Ninject for DI's and uses ServerRepository and ServerRepositoryMembershipProvider whom also are injected using Ninject.
And now I'm stuck...
Should UserRegistrationSource take the Ninject container (kernel) as a constructor argument and try to find the IUserServices service and then mediate the resolves to the Ninject kernel and return an empty Enumerable so that Autofac doesn't try to resolve anything related to IUserServices or is this the wrong approach?
Autofac supports registration sources (and more on registration sources here). A registration source is a service that the container will consult when trying to resolve a type. The source can respond, either with a means to build the type, or an empty list which indicates that the source is not able to provide the requested type.
In your case, a registration source could be implemented that will try to resolve the requested type from your Ninject container.
I'm not too familiar with Orchard but I'm guessing that it uses configuration files to configure Autofac. My suggestion is that you create a simple Autofac module that registers your registration source implementation, and that you configure Orchard to load the module from config.