Зарегистрируйте делегата или Func<Address, ValidationResult>
, используя фабричный метод, который разрешает тип, который предоставляет метод, а затем возвращает метод.
В вашем примере вы захотите разрешить OrderValidator
и вернуть его ValidateAddress
метод.
var builder = new ContainerBuilder();
// register the class that provides the method and its dependencies.
builder.RegisterType<OrderValidator>();
builder.RegisterType<SomeDependency>().As<ISomeDependency>();
// register the delegate using a factory method that resolves
// the type that provides the method and then returns the method.
builder.Register<ValidateAddressFunction>(context =>
{
var validator = context.Resolve<OrderValidator>();
return validator.ValidateAddress;
});
Это будет работать точно так же, если вы зарегистрируете Func<Address, ValidationResult>
вместо делегата:
builder.Register<Func<Address, ValidationResult>>(context =>
{
var validator = context.Resolve<OrderValidator>();
return validator.ValidateAddress;
});
Вы можете упростить регистрацию, используя расширение. Это не намного короче, но все равно помогает, если у вас есть несколько таких регистраций. Это также может помочь выразить ваше намерение, поэтому совершенно очевидно, что вы регистрируете делегата для внедрения, а не для реализации класса или реализации интерфейса.
public static class AutofacDelegateExtensions
{
public static IRegistrationBuilder<TDelegate, SimpleActivatorData, SingleRegistrationStyle> RegisterDelegateFromService<TService, TDelegate>(
this ContainerBuilder builder,
Func<TService, TDelegate> getDelegateFromService,
string sourceComponentName = null)
where TDelegate : class
{
var registrationFunction = new Func<IComponentContext, TDelegate>(context =>
{
var source = sourceComponentName == null
? context.Resolve<TService>()
: context.ResolveNamed<TService>(sourceComponentName);
return getDelegateFromService(source);
});
return builder.Register(registrationFunction);
}
}
Регистрации Autofac по умолчанию являются временными, поэтому время жизни класса, который предоставляет делегат, определяется регистрацией этого класса.
Теперь регистрация будет выглядеть так:
builder.RegisterDelegateFromService<OrderValidator, ValidateAddressFunction>(validator =>
validator.ValidateAddress);
Или, если зависимость, которая предоставляет метод - в этом случае OrderValidator
зарегистрирована с именем, и мы должны разрешить его, используя это имя:
builder.RegisterDelegateFromService<OrderValidator, ValidateAddressFunction>(validator =>
validator.ValidateAddress, "RegistrationName");