Estou tentando implementar o padrão de opções (conforme recomendado aqui: https://docs.asp.net/en/latest/fundamentals/configuration.html#options-config-objects) em um projeto com NancyFX / TinyIOC, mas não é trabalhando.
Estou registrando as opções no método Startup.cs / ConfigureServices, mas quando tento injetar as configurações na minha classe, TinyIoc lança Nancy.TinyIoc.TinyIoCResolutionException: Não foi possível resolver o tipo: AppSettings.
Acho que isso ocorre porque o padrão de opções usa Microsoft.Extensions.DependencyInjection, mas Nancy usa TinyIoc como padrão, então TinyIoc tenta resolver IOptions e falha.
Existe uma maneira de usar IOptions <> com TinyIoc?
Na pior das hipóteses, posso substituir o TinyIoc pelo MS DependencyInjection?
Este é o meu código:
Startup.cs:
public void ConfigureServices(IServiceCollection services)
{
services.AddOptions();
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
}
MyService.cs:
public SearchService(IOptions<AppSettings> config)
{
}
Erro:
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]] ``
Algumas informações extras:
"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"
},
Versão de tempo de execução DNX:
1.0.0-rc1-update1 mono
Muito obrigado.
Você não está registrando IOptions
Espero que isso faça sentido.
Tentei me registrar fazendo o seguinte:
Nancy.TinyIoc.TinyIoCContainer.Current.Register(typeof(IOptions<>), typeof(OptionsManager<>));
Qual BTW é o que services.AddOptions();
faz por baixo do capô para Microsoft.Extensions.DependencyInjection
É isto que você quer dizer?
services.Configure () pegará a configuração carregada e se registrará no MS DI para quando alguém solicitar AppSettings.
Eu adicionei isso no bootstrap personalizado:
container.Register<IOptions<ElasticSearchConfig>, OptionsManager<ElasticSearchConfig>>();
e agora o erro não acontece mais, mas infelizmente o objeto é criado vazio.
Ao depurar, percebi que isso retornará o objeto preenchido correto:
`var appSettings = app.ApplicationServices.GetService
Mas isso retornará um objeto vazio:
var appSettings = Nancy.TinyIoc.TinyIoCContainer.Current.Resolve<IOptions<AppSettings>>();
Ainda assim, TinyIoc está tomando o lugar de Ms Framework DI quando eu solicito IOptionsMicrosoft.Extensions.OptionsModel.IOptions
?
Como eu disse originalmente, você precisa passar essa instância de tipo, ou um contêiner configurado, não adianta apenas registrar o próprio tipo, pois ele precisa ser construído pela fábrica GetService.
Ei, agora entendi o que você disse, funcionou! Enviei IApplicationBuilder
para o bootstrap customizado e de lá registrei o IOptions<AppSettings>
com o valor retornado de ApplicationServices.GetService()
.
Não tenho certeza se esta é a melhor solução, pois o TinyIoc funcionará como um gateway entre meu serviço e Microsoft.Extensions.DependencyInjection
.
@RTodorov Pode ser apropriado criar uma biblioteca bootstrapper do Nancy que usa Microsoft.Extensions.DependencyInjection
como o contêiner no lugar do TinyIoC; isso já é feito para muitos contêineres diferentes.
Comentários muito úteis
@RTodorov Pode ser apropriado criar uma biblioteca bootstrapper do Nancy que usa
Microsoft.Extensions.DependencyInjection
como o contêiner no lugar do TinyIoC; isso já é feito para muitos contêineres diferentes.