Use Dependency Injection
This recipe is not a detailed discussion of the pros and cons of Dependency Injection (DI) compared to other patterns. It simply illustrates how to use it within a SAFE Stack application!
-
Create a class that you wish to inject with a dependency (in this example, we use the built-in
IConfiguration
type that is included in ASP .NET):open Microsoft.Extensions.Configuration type DatabaseRepository(config:IConfiguration) = member _.SaveDataToDb (text:string) = let connectionString = config["SqlConnectionString"] // Connect to SQL using the above connection string etc. Ok 1
Instead of functions or modules, DI in .NET and F# only works with classes.
-
Register your type with ASP .NET during startup within the
application { }
block.++ open Microsoft.Extensions.DependencyInjection application { //... ++ service_config (fun services -> services.AddSingleton<DatabaseRepository>())
This section of the official ASP .NET Core article explain the distinction between different lifetime registrations, such as Singleton and Transient.
-
Ensure that your Fable Remoting API can access the
HttpContext
type by using thefromContext
builder function.-- |> Remoting.fromValue createFableRemotingApi ++ |> Remoting.fromContext createFableRemotingApi
-
Within your Fable Remoting API, use the supplied
context
to retrieve your dependency:++ open Microsoft.AspNetCore.Http let createFableRemotingApi ++ (context:HttpContext) = ++ let dbRepository = context.GetService<DatabaseRepository>() // ... // Return the constructed API record value...
Giraffe provides the
GetService<'T>
extension to allow you to quickly retrieve a dependency from theHttpContext
.This will instruct ASP .NET to get a handle to the
DatabaseRepository
object; ASP .NET will automatically supply theIConfiguration
object to the constructor. Whether a newDatabaseRepository
object is constructed on each call depends on the lifetime you have registered it with.
You can have your types depend on other types that you create, as long as they are registering into ASP .NET Core's DI container using methods such as
AddSingleton
etc.