I'm trying to do something which I suspect is pretty basic in Autofac (I'm just getting started on IoC/DI concepts and I'm still very wobbly-kneed), but I'm running into dead-ends. Any similar info I'm finding tends to cover far more complex scenarios (delegates, generics, etc.). Mine involves just a simple ol' DirectoryInfo
constructor parameter.
I have a type that takes a DirectoryInfo
object in its constructor, and I want to register and resolve that type with Autofac:
Imports System.IO
Friend Class UpdateCommand
Implements IUpdateCommand
Public Sub New(Root As DirectoryInfo)
End Sub
End Class
Here's my registration code:
oBuilder = New ContainerBuilder
oBuilder.RegisterType(Of UpdateCommand).As(Of IUpdateCommand)()
oContainer = oBuilder.Build
But when I try to resolve it:
Using oScope As ILifetimeScope = oContainer.BeginLifetimeScope
oUpdateCommand = oScope.Resolve(Of IUpdateCommand)
End Using
I get an error:
DependencyResolutionException: None of the constructors found on type 'VsLayout.UpdateCommand' can be invoked with the available services and parameters: Cannot resolve parameter 'System.IO.DirectoryInfo Root' of constructor 'Void .ctor(System.IO.DirectoryInfo, Years, Editions)'.
That exception message contains a link to the docs, which redirects and tells us this:
Finally, you may have a parameter in your constructor that isn’t actually a service and won’t be available in the container. For example, you usually don’t register plain string or integer values in the container, but if your constructor takes a value like this, it will fail to run. In that case, you can declare a Parameter on the registration to provide the extra parameter.
That link, in turn, tells us this:
You could use a lambda expression component for that
I was hoping that was going to be my Aha! moment, but I tried modifying my registration:
oBuilder.Register(Function(x)
oRoot = New DirectoryInfo("S:\SomeDirectory")
Return New UpdateCommand(oRoot)
End Function).As(Of IUpdateCommand)()
...and then I got a different error:
ComponentNotRegisteredException: The requested service
System.Object
has not been registered.
That one throws me completely for a loop. System.Object
? Where is that supposed to come from? I am now officially lost.
How can I successfully register and resolve my UpdateCommand
type? The docs don't seem to cover this nuance, at least not that I can find.
--EDIT--
Upon further review, I see that the docs do indeed cover this exact nuance:
// Using a TYPED parameter:
builder.RegisterType<ConfigReader>()
.As<IConfigReader>()
.WithParameter(new TypedParameter(typeof(string), "sectionName"));
For some reason I looked right past that one.
I was able to get my type to resolve using the syntax suggested in this answer, which showed up in the Related questions section as soon as I posted.
Dim oParameter As Parameter
oRoot = New DirectoryInfo("S:\VisualStudio")
oParameter = New NamedParameter(NameOf(BaseCommand.Root), oRoot)
oBuilder.RegisterType(Of UpdateCommand).As(Of IUpdateCommand).WithParameter(oParameter)
It now resolves easily.