Существует два способа передачи параметров в Autofac:
При регистрации компонента :
Когда вы регистрируете компоненты, у вас есть возможность предоставить набор параметров, которые можно использовать при разрешении служб на основе этого компонента. Autofac предлагает несколько различных стратегий сопоставления параметров:
NamedParameter
- сопоставить целевые параметры по имени
TypedParameter
- сопоставить параметры цели по типу (точное совпадение типа
требуется)
ResolvedParameter
- гибкое сопоставление параметров
// Using a NAMED parameter:
builder.RegisterType<ConfigReader>()
.As<IConfigReader>()
.WithParameter("configSectionName", "sectionName");// parameter name, parameter value. It's the same of this: new NamedParameter("configSectionName", "sectionName")
// Using a TYPED parameter:
builder.RegisterType<ConfigReader>()
.As<IConfigReader>()
.WithParameter(new TypedParameter(typeof(string), "sectionName"));
// Using a RESOLVED parameter:
builder.RegisterType<ConfigReader>()
.As<IConfigReader>()
.WithParameter(
new ResolvedParameter(
(pi, ctx) => pi.ParameterType == typeof(string) && pi.Name == "configSectionName",
(pi, ctx) => "sectionName"));
NamedParameter
и TypedParameter
могут предоставлять только постоянные значения.
ResolvedParameter
может использоваться как способ подачи значений, динамически извлекаемых из контейнера, например, разрешив услугу по имени.
Если вы хотите передать в качестве параметра уже зарегистрированную службу, например, IConfiguration
, вы можете разрешить параметр, как показано ниже:
builder.RegisterType<Service>()
.As<Iervice>()
.WithParameter((pi, ctx) => pi.ParameterType == typeof(IConfiguration) && pi.Name == "configuration",
(pi, ctx) => ctx.Resolve<IConfiguration>());
При разрешении компонента :
Одним из способов передачи параметра во время выполнения в Autofac является использование метода Resolve
. Вы можете создать такой класс:
public class ContainerManager
{
public IContainer Container {get;set;}
//...
public T[] ResolveAllWithParameters<T>(IEnumerable<Parameter> parameters)
{
return Container.Resolve<IEnumerable<T>>(parameters).ToArray();
}
}
Parameter
- это абстрактный класс, принадлежащий Autofac, вы можете использовать класс NamedParameter
для передачи нужных вам параметров. Вы можете использовать класс ContainerManager
, как показано ниже:
public T[] ResolveAllWithParameters<T>(IDictionary<string,object> parameters )
{
var _parameters=new List<Parameter>();
foreach (var parameter in parameters)
{
_parameters.Add( new NamedParameter(parameter.Key, parameter.Value));
}
return ContainerManager.ResolveAllWithParameters<T>(_parameters);
}
Таким образом, вы можете передавать параметры во время выполнения, используя Dictionary<string, object>
при разрешении определенного компонента.
Использование метода расширения может быть еще проще:
public static class ContainerExtensions
{
public static T[] ResolveAllWithParameters<T>(this IContainer Container, IDictionary<string, object> parameters)
{
var _parameters = new List<Parameter>();
foreach (var parameter in parameters)
{
_parameters.Add(new NamedParameter(parameter.Key, parameter.Value));
}
return Container.Resolve<IEnumerable<T>>(_parameters).ToArray();
}
}