7

For example, I have registered class C1 with one parameter in constructor of type System.Type. I have another class (C2) with injected parameter of type C1. And I want receive typeof(C2) automatically in C1 constructor. Is it possible in some way?

Example code:

public class C1
{
  public C1(Type type) {}

  // ...
}

public class C2
{
  public C2(C1 c1) {}

  // ...
}

// Registration
containerBuilder.Register(???);
containerBuilder.Register<C2>();
Matt Hamilton
  • 200,371
  • 61
  • 386
  • 320
oryol
  • 5,178
  • 2
  • 23
  • 18

1 Answers1

7

This should do it:

builder.RegisterType<C1>();
builder.RegisterType<C2>();
builder.RegisterModule(new ExposeRequestorTypeModule());

Where:

class ExposeRequestorTypeModule : Autofac.Module
{
    Parameter _exposeRequestorTypeParameter = new ResolvedParameter(
       (pi, c) => c.IsRegistered(pi.ParameterType),
       (pi, c) => c.Resolve(
           pi.ParameterType,
           TypedParameter.From(pi.Member.DeclaringType)));

    protected override void AttachToComponentRegistration(
            IComponentRegistry registry,
            IComponentRegistration registration)
    {
        registration.Preparing += (s, e) => {
            e.Parameters = new[] { _exposeRequestorTypeParameter }
                .Concat(e.Parameters);
        };
    }
}

Any component that takes a System.Type parameter will get the type of the requestor passed to it (if any.) A possible improvement might be to use a NamedParameter rather than TypedParameter to restrict the Type parameters that will be matched to only those with a certain name.

Please let me know if this works, others have asked about the same general task and this would be good to share with them.

Nicholas Blumhardt
  • 30,271
  • 4
  • 90
  • 101
  • No, unfortunately, it doesn't work. LimitType is type of component itself (C1 in this case) – oryol Jan 24 '11 at 19:04
  • Ah - doh! - thanks for that. I'll have a think about alternatives and post them here if I find any. – Nicholas Blumhardt Jan 24 '11 at 23:51
  • Main problem is in AutowiringParameter. It always invokes resolve for children without parameters (with empty enumerable). I created similar parameter and registered it in registration.ActivatorData.ConfiguredParameters (where ActivatorData is ReflectionActivatorData) with value: registration.ActivatorData.ImplementationType. But it works only for explicit c.Resolve (and with injection of C1 itself I got 'Non of constructors found...' for C1).. – oryol Jan 29 '11 at 23:44
  • 1
    Hi- I've updated the answer to hopefully fix the problem. Let me know if you can give it a try. – Nicholas Blumhardt Jul 09 '11 at 23:55
  • Yeah, it works (I just changed pi.DeclaringType to pi.Member.DeclaringType). Much thanks. – oryol Jul 10 '11 at 17:48