DryIoc
                                
                                
                                
                                    DryIoc copied to clipboard
                            
                            
                            
                        IOption pattern in DryIoc
In ASP.Net, IOption pattern used for read config values from appsettings.json and populate concrete class. That is injected where ever required. So it would be great if we have such with DryIoc pattern.
Expectation is if could achieve with Dry Ioc pattern it would be great.
services.Configure<TransientFaultHandlingOptions>( configurationRoot.GetSection( key: nameof(TransientFaultHandlingOptions)));
Here is the IOption pattern applied in ASP.Net, (https://docs.microsoft.com/en-us/dotnet/core/extensions/options)
For example, to read the configuration values from an appsettings.json file:
{
"TransientFaultHandlingOptions": {
"Enabled": true,
"AutoRetryDelay": "00:00:07"
}
}
Create the following TransientFaultHandlingOptions class for the above setting.
public class TransientFaultHandlingOptions { public bool Enabled { get; set; } public TimeSpan AutoRetryDelay { get; set; } }
In the program.cs, (application start up) read the configuration.
IConfigurationRoot configurationRoot = configuration.Build();
    services.Configure<TransientFaultHandlingOptions>(
configurationRoot.GetSection(
    key: nameof(TransientFaultHandlingOptions)));
And the consumer uses these settings like below:
public class ExampleService { private readonly TransientFaultHandlingOptions _options;
public ExampleService**(IOptions<TransientFaultHandlingOptions> options**) =>
    _options = options.Value;
}
@sramananthula Hi,
So, are the options not injected with the current DryIoc adapter?
I have tested it in the example project for #520 (https://github.com/dadhi/DryIoc/blob/9ea3bd9a2a58034792a0df30ecfe86af2ffdd574/samples/GHIssue520/Program.cs#L11), and DryIoc has injected the options just fine https://github.com/dadhi/DryIoc/blob/9ea3bd9a2a58034792a0df30ecfe86af2ffdd574/samples/GHIssue520/Program.cs#L169
Hi, I tested with my project and it is giving following exception.
DryIoc.MefAttributedModel.AttributedModelException
HResult=0x80131509
Message=code: Error._containerErrorCount;
message: Unable to find single constructor nor marked with System.ComponentModel.Composition.ImportingConstructorAttribute nor default constructor in Microsoft.Extensions.Options.OptionsFactory<Fmr.SuperNova.Settings> when resolving: Microsoft.Extensions.Options.OptionsFactory<Fmr.SuperNova.Settings>: Microsoft.Extensions.Options.IOptionsFactory<Fmr.SuperNova.Settings> as parameter "factory" FactoryId=331 (IsSingletonOrDependencyOfSingleton)
in Singleton Microsoft.Extensions.Options.UnnamedOptionsManager<Fmr.SuperNova.Settings>: Microsoft.Extensions.Options.IOptions<Fmr.SuperNova.Settings> as parameter "options" FactoryId=330 (IsSingletonOrDependencyOfSingleton)
in resolution root Singleton Fmr.SuperNova.OptionService FactoryId=329 (IsSingletonOrDependencyOfSingleton, IsResolutionCall)
from container without scope
with Rules with {TrackingDisposableTransients} and without {ThrowOnRegisteringDisposableTransient}
with DefaultReuse=Singleton {Lifespan=1000}
with Made={FactoryMethod=
Here is my code: public class MyConfigurationProvider : IConfigurationProvider {
//Constructor
public MyConfigurationProvider([Import]IOptions<Settings> options)
    {
        _options = options.Value;
    }
}
///Option Class public class Settings { public string URL{ get; set; }
    public string KeyOne { get; set; }
}
//appsettings.json { "Settings": { "ChartIQ": "http://iichart.fmr.com/branch/develop/pure/examples/chart.html", "KeyOne": "I am from config settings" } }
//configure options builder.Services.Configure<Settings>(builder.Configuration.GetSection("Settings"));
//Failing here if the constructor takes IOptions<Settings>. It resolves with out any issues if constructor does not take //IOPtions<> var optionService = Container.Resolve<IConfigurationProvider>();
I see that you are using MEF extension?
And here is the thing that you do not control (you cannot put the Export on top of it) and should Register it: Microsoft.Extensions.Options.OptionsFactory<Fmr.SuperNova.Settings>.
Try to register OptionFactory<> in container and specify what constructor to use via made: Made.Of(optionFactoryConstructor) parameter.
for each option do we need to register this way then along with get section from config ?
Instance.Container.Register<Microsoft.Extensions.Options.IOptionsFactory<Settings>>(); builder.Services.Configure<Settings>(builder.Configuration.GetSection(key: nameof(Settings)));
Instance.Container.Register<Microsoft.Extensions.Options.IOptionsFactory>();
DryIoc.ContainerException HResult=0x80131509 Message=code: Error.RegisteringAbstractImplementationTypeAndNoFactoryMethod; message: Registering abstract implementation type Microsoft.Extensions.Options.IOptionsFactory<Fmr.SuperNova.Settings> when it is should be concrete. Also there is not FactoryMethod to use instead. Source=DryIoc StackTrace: at DryIoc.Throw.It(Int32 error, Object arg0, Object arg1, Object arg2, Object arg3) at DryIoc.ReflectionFactory.ValidateImplementationType(Type type) at DryIoc.ReflectionFactory.Of(Type implementationType, IReuse reuse, Made made, Setup setup) at DryIoc.Registrator.Register[TService,TImplementation](IRegistrator registrator, IReuse reuse, Made made, Setup setup, Nullable`1 ifAlreadyRegistered, Object serviceKey)
@sramananthula You are registering the interface instead of the implementation, that's why you are getting the error.
Looking at the MS docs https://learn.microsoft.com/en-us/aspnet/core/fundamentals/configuration/options?view=aspnetcore-6.0#use-di-services-to-configure-options
you may just call AddOptions to add them to services.
Btw, I don't see anywhere in this issue that you're doing this.
I registered Container.Register<Microsoft.Extensions.Options.OptionsFactory<Settings>>(); and also did builder.Services.AddOptions(); builder.Services.Configure<Settings>(builder.Configuration.GetSection(key: nameof(Settings))); But my class is not getting resolved though. Getting an error on .Resolve<IOptionService>(); public class OptionService : IOptionService { private Settings _options;
    public OptionService(IOptions<Settings> options) 
    {
        _options = options.Value;
    }
}
                                    
                                    
                                    
                                
@sramananthula What is the error?
Sorry. i did not added madeof the container register method. I just added like this. I am not sure whether it is correct or not.
Container.Register<OptionsFactory<Settings>>(made: Made.Of(req => typeof(OptionsFactory<Settings>)));
here is the error:
DryIoc.ContainerException
HResult=0x80131509
Message=code: Error.UnableToResolveUnknownService;
message: Unable to resolve Microsoft.Extensions.Options.IOptions<Fmr.SuperNova.Settings> as parameter "options"
in resolution root Fmr.SuperNova.OptionService: Fmr.SuperNova.IOptionService FactoryId=568
from container without scope
with Rules with {TrackingDisposableTransients} and without {ThrowOnRegisteringDisposableTransient}
with DefaultReuse=Singleton {Lifespan=1000}
with Made={FactoryMethod=
@sramananthula Ok, You are using the Made.Of wrong. Read the docs.
Regarding the initial problem with options... I don't know what is wrong with your case, but I have the working example here.
You may
- Fork the DryIoc repo:
 - Checkout the v6-dev branch (the branch itself does not relate to your issue, it just contains the example)
 - Go to the samples\GHIssue520 project and run it via 
dotnet runor debug and see the output that options are injected just fine. 
You may try to run it in isolation as well by replacing the line test.csproj
<ProjectReference Include="..\..\src\DryIoc.Microsoft.DependencyInjection\DryIoc.Microsoft.DependencyInjection.csproj" />
with
<PackageReference Include="DryIoc.Microsoft.DependencyInjection" Version="6.1.0" />
                                    
                                    
                                    
                                
Hope it will be fixed for you @sramananthula by #544