I'm trying to implement the Options Pattern (as recommended here: https://docs.asp.net/en/latest/fundamentals/configuration.html#options-config-objects) on a project with NancyFX / TinyIOC but it's not working.
I'm registering the Options on the Startup.cs/ConfigureServices method but when I try to inject the settings on my class TinyIoc throws Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: AppSettings.
I think this is because the Options Pattern uses Microsoft.Extensions.DependencyInjection but Nancy uses TinyIoc as default so TinyIoc tries to resolve IOptions and fails.
Is there a way to use IOptions<> with TinyIoc?
Worst case, can I replace TinyIoc for MS DependencyInjection?
Here's my code:
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
}
MyService.cs:
public SearchService(IOptions<AppSettings> config)
{
}
Error:
Application startup exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.InvalidOperationException: Something went wrong when trying to satisfy one of the dependencies during composition, make sure that you've registered all new dependencies in the container and inspect the innerexception for more details. ---> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: Nancy.NancyEngine ---> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: Nancy.Routing.DefaultRequestDispatcher ---> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: Nancy.Routing.DefaultRouteResolver ---> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: Nancy.Routing.RouteCache ---> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: MyProject.MyService ---> Nancy.TinyIoc.TinyIoCResolutionException: Unable to resolve type: Microsoft.Extensions.OptionsModel.IOptions
1[[MyProject.AppSettings, MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]``
Some extra info:
"dependencies": {
"Microsoft.AspNet.Server.Kestrel": "1.0.0-rc1-final",
"Microsoft.AspNet.Owin": "1.0.0-rc1-final",
"Nancy": "1.4.3",
"Microsoft.Framework.ConfigurationModel": "1.0.0-beta4",
"Microsoft.Framework.ConfigurationModel.Json": "1.0.0-beta4",
"Microsoft.Extensions.OptionsModel": "1.0.0-rc1-final"
},
DNX runtime version:
1.0.0-rc1-update1 mono
Thank you very much.
You're not registering IOptions
Hope that makes sense.
I tried registering by doing this:
Nancy.TinyIoc.TinyIoCContainer.Current.Register(typeof(IOptions<>), typeof(OptionsManager<>));
Which BTW is what services.AddOptions();
does under the hood for the Microsoft.Extensions.DependencyInjection
Is this what you mean?
services.Configure() will take the loaded configuration and register on MS DI for when someone requires AppSettings.
I added this on the custom bootstrap:
container.Register<IOptions<ElasticSearchConfig>, OptionsManager<ElasticSearchConfig>>();
and now the error doesn't happen anymore but unfortunately the object is created empty.
When debugging, I realised that this will return the correct populated object:
`var appSettings = app.ApplicationServices.GetService
But this will return an empty object:
var appSettings = Nancy.TinyIoc.TinyIoCContainer.Current.Resolve<IOptions<AppSettings>>();
Still, TinyIoc is taking the place of Ms Framework DI when I request for IOptionsMicrosoft.Extensions.OptionsModel.IOptions
?
Like I said originally, you need to pass that type instance in, or a configured container, its no good just registering the type itself as it needs to be constructed by the GetService factory.
Hey, now I get what you said, it worked! I sent IApplicationBuilder
to the custom bootstrap and from there registered the IOptions<AppSettings>
with the value returned from ApplicationServices.GetService()
.
I'm not sure this is the best solution though, since TinyIoc will act as a gateway between my service and Microsoft.Extensions.DependencyInjection
.
@RTodorov It may be appropriate to create a Nancy bootstrapper library that uses Microsoft.Extensions.DependencyInjection
as the container in place of TinyIoC, this is done for many different containers already.
Most helpful comment
@RTodorov It may be appropriate to create a Nancy bootstrapper library that uses
Microsoft.Extensions.DependencyInjection
as the container in place of TinyIoC, this is done for many different containers already.