Autofac: Allow a specific dependency on a named instance

Using Autofac I would like to register a component and specify which specific dependency will be resolved for the named instance.

I found samples like the following using constructor injection, which is almost what I want.

builder.Register(c => new ObjectContainer(ConnectionStrings.CustomerDB))
    .As<IObjectContainer>()
    .Named("CustomerObjectContainer");

builder.Register(c => new ObjectContainer(ConnectionStrings.FooDB))
    .As<IObjectContainer>()
    .Named("FooObjectContainer");

builder.Register(c => new CustomerRepository(
    c.Resolve<IObjectContainer>("CustomerObjectContainer"));

builder.Register(c => new FooRepository(
    c.Resolve<IObjectContainer>("FooObjectContainer"));

      

However, I need this with introducing properties and I don't want to list all dependencies.

Something like:

builder.Register<CustomerRepository>().With<IObjectContainer>("CustomerObjectContainer");    
builder.Register<FooRepository>().With<IObjectContainer>("FooObjectContainer");

      

Combining all undefined dependencies must happen on unnamed instances.

Thanks, Alex

[ADDITION FROM ANSWER FROM Danielg]

An overload for type resolution for any property of that type.

    public static IRegistrationBuilder<TLimit, TReflectionActivatorData, TStyle> WithDependency<TLimit, TReflectionActivatorData, TStyle, TProperty>(
        this IRegistrationBuilder<TLimit, TReflectionActivatorData, TStyle> registration,
        Func<IComponentContext, TProperty> valueProvider)
        where TReflectionActivatorData : ReflectionActivatorData
    {
        return registration.WithProperty(new ResolvedParameter((p, c) =>
            {
                PropertyInfo prop;
                return p.TryGetDeclaringProperty(out prop) &&
                    prop.PropertyType == typeof(TProperty);
            },
            (p, c) => valueProvider(c)));
    }

      

+3


source to share


1 answer


I don't think autofac has a shorthand way to do this yet, but it is possible with a little effort.

I wrote an extension method that does this. Throw it into a static extension class and you should be fine. The extension also shows you how to do it a long way.

public static IRegistrationBuilder<TLimit, TReflectionActivatorData, TStyle> WithResolvedProperty<TLimit, TReflectionActivatorData, TStyle, TProperty>(
    this IRegistrationBuilder<TLimit, TReflectionActivatorData, TStyle> registration,
    string propertyName, Func<IComponentContext, TProperty> valueProvider)
        where TReflectionActivatorData : ReflectionActivatorData
{
    return registration.WithProperty(new ResolvedParameter((p, c) =>
                                                               {
                                                                   PropertyInfo prop;
                                                                   return p.TryGetDeclaringProperty(out prop) &&
                                                                          prop.Name == propertyName;
                                                               },
                                                           (p, c) => valueProvider(c)));
}

      



Ignore the super long method signature, autofac registration is very verbose.

You can use an extension like this.

builder.RegisterType<Foo>()
    .WithResolvedProperty("Bar", c => c.Resolve<IBar>());

      

+5


source







All Articles