IDependencyResolver interface implementation in F# Web API

651 views Asked by At

I am re-writing a C# ASP.NET Web API application in F#. I have Models and Controllers done and I moved onto MyDependencyResolver that implements IDependencyResolver.

I am having a problem implementing the GetService method, whose signature in C# is:

object GetService(System.Type serviceType)

So I need to return an obj and take a System.Type as a parameter.

This is what I have so far in F#:

type MyDependencyResolver() =
    interface System.Web.Http.Dependencies.IDependencyResolver with
        member this.BeginScope() : IDependencyScope =
            this :> IDependencyScope

        member this.GetService(serviceType:Type) : obj =

            if (serviceType = typeof<Controllers.HomeController>) then
                let homeController = new Controllers.HomeController(arg1, arg2, arg3, arg4)
                homeController :> obj
            // ???
            elif (serviceType = typeof<_>) then
                null           

        member this.GetServices (serviceType: Type) :IEnumerable<obj> =
            let x = new List<obj>()
            x :> IEnumerable<obj>

        member this.Dispose() =
            ()

So if serviceType is of type HomeController I want to return an instance of HomeController, and if it's of any other type I want to return null. How do I do that in F#?

Edit:

GetService method in C#:

 public object GetService(Type serviceType)
 {
    if (serviceType == typeof(Controllers.HomeController)){
        return new Controllers.HomeController(arg1, arg2, arg3, arg4);
    }
    return null;
 }
1

There are 1 answers

2
CaringDev On

You could just use Activator.CreateInstance(serviceType) but where do you get the constructor arguments from?

In my projects I use Unity, which is configured as follows:

let private ConfigureUnity (config : HttpConfiguration) =
        let rec unityResolver (container : IUnityContainer) =
            { new IDependencyResolver with
                member this.BeginScope() =
                    unityResolver(container.CreateChildContainer()) :> IDependencyScope
                member this.GetService serviceType =
                    try container.Resolve(serviceType) with
                        | :? ResolutionFailedException -> null
                member this.GetServices serviceType = 
                    try container.ResolveAll(serviceType) with
                        | :? ResolutionFailedException -> Seq.empty
                member this.Dispose() = container.Dispose()
            }

        config.DependencyResolver <- (new UnityContainer())
            .RegisterType<IFoo, FooImplementation>(new HierarchicalLifetimeManager())
            .RegisterType<IBar, BarImplementation>(new HierarchicalLifetimeManager())
            |> unityResolver

Classes (such as your controllers) are then resolved automatically and Unity will create dependencies (the constructor arguments) for you. Using other dependency injection frameworks should be straightforward.