Autofac: устранение определенной зависимости для именованного экземпляра - PullRequest
3 голосов
/ 15 марта 2012

Используя Autofac, я хотел бы зарегистрировать компонент и указать конкретную зависимость, которая должна быть разрешена для именованного экземпляра.

Я нашел примеры, подобные приведенным ниже, с использованием внедрения в конструктор, что почти то, что мне нужно.

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"));

Однако мне нужно это с внедрением свойства, и я не хочу указывать все зависимости.

Что-то вроде:

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

Сборка всехНеуказанные зависимости должны возникать с неназванными экземплярами.

Спасибо, Алекс

[ДОБАВЛЕНИЕ К ОТВЕТУ ОТ Даниэля]

Перегрузка для разрешения по типу для любого свойства этого типа.

    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)));
    }

1 Ответ

5 голосов
/ 15 марта 2012

Я не думаю, что у autofac есть сокращенный способ сделать это, но это возможно с небольшими усилиями.

Я написал метод расширения, который делает это.Брось его в класс статического расширения и у тебя все будет хорошо.Расширение также показывает, как проделать этот долгий путь.

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)));
}

Не обращайте внимания на сигнатуру супердлинного метода, автоматические регистрации очень подробны..

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