Tom Thorne
Tom Thorne

Reputation: 214

Autofac: how do I pass a reference to the component being resolved to one of its dependents?

With the following:

public class AClass
{
  public ADependent Dependent { get; set; }
}
public class ADependent
{
  public ADependent(AClass ownerValue) {}
}

with the following registrations...

builder.RegisterType<AClass>().PropertiesAutowired().InstancePerDependency();
builder.RegisterType<ADependent>().PropertiesAutowired().InstancePerDependency();

When I resolve an AClass, how do I make sure that 'ownerValue' is the instance of AClass being resolved, and not another instance? Thx

FOLLOW ON

The example above doesn't really catch the problem properly, which is how to wire up ADependent when registering when scanning... for example

public class AClass : IAClass
{
  public IADependent Dependent { get; set; }
}
public class ADependent : IADependent
{
  public ADependent(IAClass ownerValue) {}
}

// registrations...

  builder.RegisterAssemblyTypes(assemblies)
    .AssignableTo<IAClass>()
    .As<IAClass>()
    .InstancePerDependency()
    .PropertiesAutowired();

  builder.RegisterAssemblyTypes(assemblies)
    .AssignableTo<IADependent>()
    .As<IADependent>()
    .InstancePerDependency()
    .PropertiesAutowired();

The function I am looking for really is another relationship type like

public class ADependent : IADependent
{
  public ADependent(OwnedBy<IAClass> ownerValue) {}
}

The OwnedBy indicates that ownerValue is the instance that caused ADependent to created. Does something like this make sense? It would certainly make wiring up UI components a breeze.

Upvotes: 1

Views: 662

Answers (2)

Steven
Steven

Reputation: 172606

You can register a lambda to do the trick:

builder.Register<AClass>(_ =>
{
    var a = new AClass();
    a.Dependent = new ADependent(a);
    return a;
});

Upvotes: 0

Nicholas Blumhardt
Nicholas Blumhardt

Reputation: 31757

To extend Steven's approach, you can even Resolve() the second class, passing the first instance as a parameter:

builder.RegisterType<ADependent>();
builder.Register<AClass>(c =>
{
   var a = new AClass();
   a.Dependent = c.Resolve<ADependent>(TypedParameter.From(a));
   return a;
});

Upvotes: 1

Related Questions