FrozenVeg
FrozenVeg

Reputation: 11

Autofac property injection for manually instantiated objects

Suppose I have the following:

public class Test
{
    public IDependency Dependency { get; set; }
}

IDependency and Test are registered in my Autofac builder. My IDependency resolution works fine, but what I'm trying to achieve is to be able to return new instances of Test in the code (e.g. return new Test();) and have it's IDependency properties prepopulated by Autofac.

What I've tried in my container:

builder.Register(x => new Test {
    x.Resolve<IDependency>()
}); 

However, everytime I new Test() in the code, it's IDependency property is null. Is that possible?

(for reference, my train of thought leading to this attempt was that I initially did constructor injection for Test but then realized that in some cases I need to manually construct new Test() instances in the code, and couldn't figure out what to put to satisfy the constructor signature public Test(IDependency dependency) and still have Autofac resolve that dependency)

Upvotes: 1

Views: 2044

Answers (1)

olitee
olitee

Reputation: 1683

Just a thought - are you saying you need some mechanism to construct a new instance of the Test object (with it's dependencies injected) programatically in your code?

There's a handy feature built into Autofac to obtain factory for a registered type. I'd suggest you switch back to constructor injection:

public class Test
{
    public Test(IDependency dependency)
    {
        Dependency = dependency;
    }

    public IDependency Dependency { get; }
}

and then register the types with Autofac as:

cb.ResisterType<MyDependency>().As<IDependency>();    
cb.RegisterType<Test>();

Then all you need to do wherever you're wanting to manually construct a new instance of Test() is request a Func<Test> in your constructor. Autofac will generate a factory allowing you to instansiate a Test class whenever you like ... but without tight coupling to the Autofac library:

public class SomeAppLogic
{
    public SomeAppLogic(Func<Test> testFactory)
    {
        // Some app logic
        for (int i = 0; i < 10; i++)
        {
            // Invoke the testFactory to obtain a new instance 
            // of a Test class from the IoC container
            Test newTestInstance = testFactory.Invoke();
        }
    }
}

Autofac refers to this as 'Dynamic Instantiation', which is covered here: https://autofaccn.readthedocs.io/en/latest/resolve/relationships.html#dynamic-instantiation-func-b

Upvotes: 1

Related Questions