Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    arc95
    @arc95
    Hi all
    Been on the struggle bus with that since last week
    Mario Adam
    @i-dentify

    Hi all - I have a question on resolving keyed components. I have registered a type "ClientContext" several times as a keyed component with varying keys. As far as I understood the real resolving is performed once a given key is accessed, right? So my IIndex<ClientContextType, ClientContext> contextsregistration performs its resolving first when I e.g. access a particular registration via var o = contexts[ClientContextType.User].

    Now I have that situation that ONE keyed registration would need a parameter for initialization. So there would be var o = contexts[ClientContextType.User] and var o = contexts[ClientContextType.App]('foo'). Is this even possible?

    Alistair Evans
    @alistairjevans

    Not using IIndex<TKey, TValue>, no. However, if you declare your own lookup interface similar to IIndex, but with methods that allow you to pass parameters, and an implementation for the same, you can do it fairly easily. See the code for KeyedServiceIndex in Autofac for inspiration.

    When resolving a component in KeyedServiceIndex, we use IComponentContext.ResolveService, which has an overload that can take parameters that you can use.

    You'll need to register your new custom generic index:

    // Register your custom generic lookup.
    var builder = new ContainerBuilder();
    builder.RegisterGeneric(typeof(ParameterisedKeyedServiceIndex<>)).As(typeof(IParameterisedIndex<>));
    Jerome Haltom
    @wasabii
    Is anybody still doing attribute registation?
    I wrote my own attribute registration library. Was wondering if the existing one is still... like... used?
    RyannnnnnR
    @RyannnnnnR
    Im not sure if my test is invalid or if i've found a bug but I'm using Autofac moq and Autofac dependency injection. This is the exception I get:
    Unable to retrieve Autofac root lifetime scope from service provider of type Castle.Proxies.IServiceProviderProxy.
    Test:
    https://github.com/RyannnnnnR/invoicer-backend-microservices/blob/master/src/Invoicer.CommonTest/CommandHandlerTests.cs
    Code:
    https://github.com/RyannnnnnR/invoicer-backend-microservices/blob/master/src/Invoicer.Common/CommandBus.cs
    RyannnnnnR
    @RyannnnnnR
    More genenrally, how would you test the components that use the AutofacRoot as a single source of truth for the container instantiation?
    Jerome Haltom
    @wasabii
    I have a fun problem. I need to override a service registration. But, if the registation already exists, I need an instance of the existing registration to build my new one on.
    Obviously can't just resolve it, since that would be circular.
    Nicholas Blumhardt
    @nblumhardt
    @wasabii adding it as an IRegistrationSource might do the job?
    Sami Al Khatib
    @alsami

    Im not sure if my test is invalid or if i've found a bug but I'm using Autofac moq and Autofac dependency injection. This is the exception I get:
    Unable to retrieve Autofac root lifetime scope from service provider of type Castle.Proxies.IServiceProviderProxy.
    Test:
    https://github.com/RyannnnnnR/invoicer-backend-microservices/blob/master/src/Invoicer.CommonTest/CommandHandlerTests.cs
    Code:
    https://github.com/RyannnnnnR/invoicer-backend-microservices/blob/master/src/Invoicer.Common/CommandBus.cs

    Do you have a sample repository somewhere? Then I could look into it.

    RyannnnnnR
    @RyannnnnnR
    @alsami Hey! Sorry for the delay on this, I also forgot to update the channel - I asked on StackOverflow and came to the conclusion DI shouldn't be mocked. https://stackoverflow.com/questions/62640392/mocking-autofac-root-from-iserviceprovider
    spooky
    @spooky
    hello, is there anyone here who could answer a question/provide info about best practices regarding autofac performance (for a specific case)?
    Sami Al Khatib
    @alsami

    hello, is there anyone here who could answer a question/provide info about best practices regarding autofac performance (for a specific case)?

    I can try. What's the case you are speaking about?

    spooky
    @spooky
    I have a factory registered like this:
            containerBuilder.Register<Func<Type, TA, TB, TC>>(c =>
            {
                var context = c.Resolve<IComponentContext>();
    
                return (type, a, b) =>
                    context.Resolve(type, new TypedParameter(typeof(TA), a), new TypedParameter(typeof(TB), b)) as TC;
            });
    that's called a lot of times and each call is ~23ms
    is there a better (faster) way do this? (because I can't really influence the number of calls :/ )
    note: there are multiple types implementing TC which is an interface
    Sami Al Khatib
    @alsami
    @spooky Currently it's InstancePerDependency(). Which will create one Instance for each requesting service. Do you need it to be in that scope?
    spooky
    @spooky
    I could use InstancePerLifetimeScope but in some cases that will be too large :/
    for web usage it would be fine, but it's also used in a windows service that's doing multiple calls
    although it being a factory... that should be fine I guess
    Sami Al Khatib
    @alsami
    Hm, no other idea here to be honest. Dealing with reflection is always time consuming, which is pretty much the case here.
    Maybe @alistairjevans has an idea
    @spooky when it's running in a windows service, does the time matter that much?
    spooky
    @spooky
    yes, it does matter unfortunately. The biggest problem it seems is the number of calls to it, but as I mentioned, I can't change that :/. I'll try to scope the factory registration and check if that improves anything. Thanks for the help
    Evan Raffel
    @evman182
    Don't know if this is something autofac supports (or the dotnet core DI container), but what I'd like is to able to have a registration that's normally transient, but for a specific "Owner", is injected within a new lifetime scope. Not sure I'm saying this right, but I'd be glad to come up with a quick code example.
    Is this possible via registration. It seems like I can do it by having the constructor parameter be Owned<>, but I'd like to do it without autofac bleeding into my other classes
    Alistair Evans
    @alistairjevans
    Its not possible at registration time I'm afraid.
    If you just want to avoid leaking Owned into the rest of your classes, you could consider wrapping Owned in your own class, so the Owned reference is limited to a single place?
    Evan Raffel
    @evman182
    Thanks. I'll see what my teammates want to do. This is just one of several possible solutions to what I'm trying to solve
    AKruimink
    @AKruimink

    Quick question
    I got a factory that creates settings for me, i would like to register it in a way that i can have them resolved
    Currently i got

    builder.RegisterType<SettingFactory>().As<ISettingFactory>().SingleInstance();
    builder.Register(x => x.Resolve<ISettingFactory>().Create<ApplicationSettings>()).As<ISetting<ApplicationSettings>>();

    That works fine, the factory itself already own a cashe and just uses it that way.
    The only thing i would like to improve is to allow for generics on ISetting

    The factory returns an ISetting<SettingType>, with the way my current code works i would need to register every settings type that exists>
    Is there anyways to make it so that i can have a depenency on ISetting<SomeType> and that Autofac uses SomeType to create the ISettings, not really caring if it's registered or not (simply said, like a generic)

    I know about RegisterGeneric, but i cant really get it to work with that either
    Sami Al Khatib
    @alsami
    @AKruimink might this be of help?
    You will need to wait for v6 though.
    If I understand your requirement correctly, this should be what you need.
    AKruimink
    @AKruimink

    @alsami Thank you for the reply, and yes i think that is what im looking for. Altho correct me if im wrong.
    My current code (that works) functions as follows.

    public SomeClass(ISettings<ApplicationSettings> appSettings)
    {
            // Constructor Code
    }

    So Autofac would have to inject a ISettings with the generic type ( in this case of type ApplicationSettings).
    My current Autofac module is setup as follows.

    builder.RegisterType<SettingFactory>().As<ISettingFactory>().SingleInstance();
    builder.Register(x => x.Resolve<ISettingFactory>().Create<ApplicationSettings>()).As<ISetting<ApplicationSettings>>();

    I register a single isntance of my SettingsFactory (single as the factory own's its own cashe system).
    Then i register the ISetting<ApplicationSettings> through the use of my Factory, the registration resolves my SettingsFactory and then uses it's Create method that creates an ISetting instance based on a given generic type

    public ISetting<TSetting> Create<TSetting>() where TSetting : new()
            {
                // creates or resolves the instance (if cashe exists)
            }

    The only thing i would like to improve is the

    builder.Register(x => x.Resolve<ISettingFactory>().Create<ApplicationSettings>()).As<ISetting<ApplicationSettings>>();

    That the ApplicationSettings could be used as a generic, so i don't have to register every single possible setting's type, but can just say, i want a ISetting of wat ever type and let my own factory deal with the creation.

    If i understand that PR correctly that generic usage would be possible in v6?

    Dima Enns
    @Yeah69
    Init-members on properties (C#9.0) could be an opportunity for elegant property injection. Are there any plans to utilize this new language feature in Autofac?
    Dima Enns
    @Yeah69

    I have tried it myself with the .Net 5.0 preview:

    using System;
    using System.Linq;
    
    internal class Test
    {
        public int TestProp { private get; init;  }
    
        public override string ToString()
        {
            return TestProp.ToString();
        }
    
        public static void Main()
        {
            // Sanity check
            Console.WriteLine("Hello World!"); // Hello World!
    
            var test = new Test { TestProp = 69 };
    
            // Check normal way
            Console.WriteLine($"Hello {test}!"); // Hello 69!
    
            Type type = typeof(Test);
            var propertyInfo = type.GetProperties().First();
            var test2 = Activator.CreateInstance<Test>();
    
            propertyInfo.SetValue(test2, 23);
    
            // Check reflection way
            Console.WriteLine($"Hello {test2}!"); // Hello 23!
        }
    }

    Seems like reflection doesn't distinguish between set and init.

    Sami Al Khatib
    @alsami

    Init-members on properties (C#9.0) could be an opportunity for elegant property injection. Are there any plans to utilize this new language feature in Autofac?

    Currently there are no plans for init-properties and C# 9 features. Feel free to open a feature-request.
    https://github.com/autofac/Autofac/issues/new?assignees=&labels=&template=feature_request.md&title=

    Nirajan Kharal
    @nkharal
    Having issue with using Autofac with IHostBuilder. I am able to resolve service after builder.Build(). However, when i run application with
    .UseServiceProviderFactory(new AutofacServiceProviderFactory())
    .ConfigureServices((hostContext, services) =>
    {
    services.AddHostedService<SomeService>();
    });
    I get "An exception was thrown while activating λ:Microsoft.Extensions.Hosting.IHostedService[] . SomeService" . DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder. Any help will be appreciated?
    Sami Al Khatib
    @alsami
    The stack trace should tell you which class can not be resolved. If you post the whole stack trace I might be able to help you.
    What dependencies does someservice have? Did you register all of them?
    Nirajan Kharal
    @nkharal
    Hi ... I am able to resolve them all if I don't use IHostBuilder so i feel i am missing some configuration. Autofac is working fine when i use it with topself. When trying to migrate to WorkerService is where I get problem.
    Sami Al Khatib
    @alsami
    Would be good if you could provide a sample or the whole stack trace. In general the way you use it seems to be fine.
    Nirajan Kharal
    @nkharal
    I have direct messaged you the stack trace
    Nirajan Kharal
    @nkharal
    Thanks @alsami for all your help