Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autofac: How to use construction injection on class with dependency to another object function output

This question is about IoC in general, but I'm using Autofac, so an Autofac solution would be great.

So assume the following classes:

class A
{
    IEnumerable<B> GetBs();
}

class B 
{
    // Some code
}

class C
{
    readonly IEnumerable<B> bs;

    C(IEnumerable<B> bs)
    {
        this.bs = bs;
    }
}

class Program
{
    static void Main(string[] args)
    {
        var builder = new ContainerBuilder();
        builder.Register<A>();
        builder.Register<C>();

        var container = builder.Build();
        var c = container.Resolve<C>();
        // do something with c
    }
}

the above Main will fail.

I've noticed that I can solve this by adding this line of code:

builder.Register(c => c.Resolve<A>().GetBs())

However, that doesn't feel right. Any other way to achieve this? Or design changes?

like image 404
Ben Avatar asked Feb 01 '26 22:02

Ben


1 Answers

As given, this class structure looks perfectly fine. You are properly using Constructor Injection and using the static structure of the classes to communicate invariants and relationships. On the level of information provided here, I think the only thing missing is a Guard Clause in the C constructor :)

On a conceptual level it's harder to answer whether or not this is a good design. That depends on context not provided here. Is B a Service or an Entity? What is the intended source of Bs?

As a general rule of thumb we should only inject Services, but handle Entities with Services (such as Repositories or Gateways or whatnot), so if B represents a Service it would be okay to inject it into C. If it represents an Entity, then it becomes suspect - unless C is also an Entity...

On another note you can ask about the canonical source of Bs. If A truly is meant to be the container of Bs, then the above solution is correct (and idiomatic Autofac code). If the Bs really have a different origin, resolving them through A may be a hack...

like image 171
Mark Seemann Avatar answered Feb 04 '26 12:02

Mark Seemann