Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Repo info
Activity
    Sami Al Khatib
    @alsami
    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
    Jerome Haltom
    @wasabii
    Hey friends. I'm trying to figure out the best way to add a generic registration to a IComponentRegistryBuilder (from a callback). The RegisterGeneric extension method is only available on teh ContainerBuilder, it seems. And all the OpenGeneric stuff is internal. Any ideas?
    Jerome Haltom
    @wasabii
    Well, so, I got it to work by passing the ContainerBuilder through, and using reflection to access RegistrationBuilder and OpenGenericRegistrationSource. But that's all lame.
    Jerome Haltom
    @wasabii
    Also, how the heck are you supposed to manually invoke an Activator now to create an instance?
    Evertyhing was replaced with ServiceRegistration, instead of the RegistrationAccessor delegates.... and Activator on the registration no longer just has an activate method.
    Alex Meyer-Gleaves
    @alexmg
    @wasabii I assume you a referring to an Autofac build callback? Are you resolving a service after container build that is providing the information for the open generic registrations? If the open generic registrations are for a known open generic type you may be able to create your own IRegistrationSource for them that is updated after build with additional known concrete types before they are resolved.
    Alex Meyer-Gleaves
    @alexmg
    Is it the open generic type you don't know ahead of time? The same approach would still work assuming the scenarios don't invole some of the more complex edge cases covered in the OpenGenericRegistrationSource.
    If you can provide some more detail we might be able to figure something out for you that doesn't involve falling back to reflection based hacks. It's never nice to have that kind of ticking time bomb lurking around in your code. 🙂
    Jerome Haltom
    @wasabii
    @alexmg Yeah, working on my MS DI adaptor. Need to handle generics in it. But I do all my work in a BuildCallback. At which time I only have a IContainerRegistryBuilder.
    Before 6 I had copied the entire OpenGeneric hierarchy of code into my own, and just added a Source. That worked. But it was ugly. What I've done now is used reflection to create a RegistrationBuilder and a OpenGenericRegistrationSOurce. Also, not great.
    Jerome Haltom
    @wasabii
    (I have my own MS DI Populate method, that supports some of the more esoteric users of MS DI, that actually try to REMOVE things from ServiceCollection).
    markelli
    @markelli
    When I create a LifetimeScope through dependency in the constructor like MyViewModel(ILifetimeScope scope) then I should be calling dispose on that scope object in the dispose of MyViewModel right? And that will result in disposing of all the objects resolved using that scope?
    Alex Meyer-Gleaves
    @alexmg

    @markelli The constructor of MyViewModel is not creating the ILifetimeScope instance, it is receiving a reference to the ILifetimeScope that it is being created in. Because the view model did not create the lifetime scope it should not be disposing it. The lifetime scope should be disposed by the thing that created it.

    I would recommend having a read of this blog post from Nick to get a better understanding of lifetime scopes. It written some time ago but remains entirely relevant.

    https://nblumhardt.com/2011/01/an-autofac-lifetime-primer/

    @wasabii Is the adaptor open source or something from your work? How does it fit in with the existing Microsoft abstraction for DI?
    markelli
    @markelli

    @alexmg If I'm creating that MyViewModel via autofac though then the only object that by default knows about that instance of ILifetimeScope would be the MyViewModel no? So where else would I dispose of it?

    In this specific case I have another object like MyFirstViewModel which has a call to scope in it to scope.Resolve<MyViewModel>() but the only way it would know about the scope created for MyViewModel is if that were then exposed as a property or something of that nature.

    Alex Meyer-Gleaves
    @alexmg
    Is the scope you referred to in MyFirstViewModel a new child lifetime scope? If it is not and MyViewModel is resolved from the root lifetime scope disposing it would not be a good thing. You might need to provide some more example code so we can better understand your scenario.
    Jerome Haltom
    @wasabii
    @alexmg Autofac.ServiceFabric: I notice it's waiting on a release, but otherwise seems done?
    @alexmg Oh, old question I didn't notice. My adaptor is open source, and on github. https://github.com/alethic/Cogito.Autofac/tree/master/Cogito.Autofac.DependencyInjection
    It reimplements IServiceCollection. With some build callbacks, and a local cache.
    Basically, Add* methods are free to remove stuff from the collection, up until Flush is invoked, which is done in a build callback.
    There are a few Add methods in the wild which actually try to remove crap from the IServiceCollection before adding their own. HttpClientFactory was one of em.
    Jerome Haltom
    @wasabii
    So... yeah... my ComponentRegistryServiceCollection, actually generates ServiceDescriptors in REVERSE, so during the Populate method, whatever Add* methods you're using actually have a view of stuff already in the container. So they can check if it already exists (some do this). And they can remove those added in the current 'transaction' (time before Flush is invoked).
    Jerome Haltom
    @wasabii
    Oh. I left off the entire point: you can call Populate multiple times and all that works. Because I break down stuff by Modules. So, lots of independent calls to Populate.
    Alex Meyer-Gleaves
    @alexmg
    @wasabii Autofac.ServiceFabric 4.0.0 is now released to NuGet. Thanks for the link to the project.
    Jerome Haltom
    @wasabii
    Thanks.
    Jerome Haltom
    @wasabii
    @alexmg Obviously, I'd prefer you to take all my code and incorporate it, instead of maintaining my own version. But I'm doing things quite differently.
    Jerome Haltom
    @wasabii
    Oh, and also, I'm actually replacing the WebHost hosting service provider with Autofac, instead of leaving it in MS DI.
    Jerome Haltom
    @wasabii
    Any hope of supporting ByRef ctor parameters?
    Jerome Haltom
    @wasabii
    Clarity: I mean for 'in' parameters.
    Alex Meyer-Gleaves
    @alexmg

    Hey @wasabii

    Obviously, I'd prefer you to take all my code and incorporate it, instead of maintaining my own version. But I'm doing things quite differently.

    We have too many packages already and need to start offloading some if anything. Do you still require the functionality provided in your package? It is quite different and seems like you might be continually fighting battles on multiple fronts.

    Any hope of supporting ByRef ctor parameters? Clarity: I mean for 'in' parameters.

    Looks like there is already a related issue open for that. #1226

    Jerome Haltom
    @wasabii
    I believe I do require it, yes. It's the only way to get Modules to work right with MS DI.
    Multiple modules may independently invoke Populate. Each one of these has a habit of invoking, say, AddOptions as an example. That results in multiple ServiceCollections created, and dumped into the container. So multiple registrations of Options framework.
    Same with Logging. It screws stuff up in my experience. You end up configuring logging in one part of the app, only to have some random Add* call elsewhere call AddLogging a second time and supercede your stuff.
    Jerome Haltom
    @wasabii
    The way to avoid it is to put all MS DI calls in a single call to populate. But you can't do that with modules.
    Stefan Ossendorf
    @StefanOssendorf
    @wasabii Because of that I'm encouring my team to move to use MS DI for registration and autofac only as DI provider. To avoid this s... :-/ Sad but well some stuff is only available for MS DI >_>
    Jerome Haltom
    @wasabii
    I just fixed up the AF integration so you can call Populate multiple times.
    Jerome Haltom
    @wasabii

    I have a real question. Imagine I have a set of services. They all depend on each other by resolving each other through interfaces. There's a set of HostedServices that go along with them as well.

    I want to register this block of services twice. But have each block only resolve from amongst itself. So, two copies of this set of services, that only depend on other services within the same set. Named services are the idea. Except, I want to make the names of the ctor injectors dynamic to the name of the set, also.

    Or, register it all twice, in two separate Lifetime Scopes. However, it's not really a lifetime scope. Because there's HostedServices, and those really need to be started by the top-level generic Host.