1

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)

FrozenVeg
  • 11
  • 2
  • You should use Autofac to resolve dependencies, when you're using `new` keyword it's nothing but constructor of the real implementation and not the abstraction. I would suggest define `ITest` kind of interface and register it alongside with IDependency. – mexanichp Feb 06 '19 at 15:40
  • Also if you want to manually construct the objects - you should manually inject theses objects. I think autofac allows that, you may take a look on this question: https://stackoverflow.com/questions/24876393/what-is-the-proper-way-to-create-objects-which-require-parameters-using-autofac – mexanichp Feb 06 '19 at 15:43
  • It appears your code snippet may have a typo - the `x.Resolve()` isn't being assigned to any property. – Travis Illig Feb 07 '19 at 15:54

1 Answers1

1

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

olitee
  • 1,683
  • 10
  • 12
  • Totally correct, though I might add you can do `lifetimeScope.InjectProperties(theObject)` and Autofac will inject the properties on a previously constructed object. – Travis Illig Feb 07 '19 at 15:57