Passing parameters to constructors using Autofac

前端 未结 4 1465
说谎
说谎 2021-01-31 02:42

I\'m very new to autofac so it\'s possible that I\'m completely misusing it.

Let\'s say I have a class that has this structure:

public class HelperClass          


        
4条回答
  •  余生分开走
    2021-01-31 02:54

    There are two ways to pass parameters in Autofac:

    When you are registering the component:

    When you register components, you have the ability to provide a set of parameters that can be used during the resolution of services based on that component. Autofac offers several different parameter matching strategies:

    • NamedParameter - match target parameters by name
    • TypedParameter - match target parameters by type (exact type match required)
    • ResolvedParameter - flexible parameter matching

      // Using a NAMED parameter:
      builder.RegisterType()
         .As()
         .WithParameter("configSectionName", "sectionName");// parameter name, parameter value. It's the same of this: new NamedParameter("configSectionName", "sectionName")
      
      // Using a TYPED parameter:
      builder.RegisterType()
         .As()
         .WithParameter(new TypedParameter(typeof(string), "sectionName"));
      
      // Using a RESOLVED parameter:
      builder.RegisterType()
         .As()
         .WithParameter(
           new ResolvedParameter(
             (pi, ctx) => pi.ParameterType == typeof(string) && pi.Name == "configSectionName",
             (pi, ctx) => "sectionName"));
      

      NamedParameter and TypedParameter can supply constant values only.

      ResolvedParameter can be used as a way to supply values dynamically retrieved from the container, e.g. by resolving a service by name.

    In case you want to pass as parameter a service that is already registered, eg, IConfiguration, you can resolve the parameter as I show below:

        builder.RegisterType()
               .As()
               .WithParameter((pi, ctx) => pi.ParameterType == typeof(IConfiguration) && pi.Name == "configuration",
                              (pi, ctx) => ctx.Resolve());
    

    When you are resolving the component:

    One way to pass parameter at runtime in Autofac is using the Resolve method. You could create a class like this:

    public class ContainerManager
    {
      public IContainer Container {get;set;}
      //...
      public T[] ResolveAllWithParameters(IEnumerable parameters)
      {
        return Container.Resolve>(parameters).ToArray();
      }
    }
    

    Parameter is an abstract class that belongs to Autofac, you can use the NamedParameter class to pass the parameters that you need. You can use the ContainerManager class as I show below:

        public T[] ResolveAllWithParameters(IDictionary parameters )
        {
            var _parameters=new List();
            foreach (var parameter in parameters)
            {
                _parameters.Add( new NamedParameter(parameter.Key, parameter.Value));
            }
            return ContainerManager.ResolveAllWithParameters(_parameters);
        }
    

    This way you can pass the parameters at runtime using a Dictionary when you are resolving an specific component.

    Using an Extension Method could be even more simple:

    public static class ContainerExtensions
    {
        public static T[] ResolveAllWithParameters(this IContainer Container, IDictionary parameters)
        {
            var _parameters = new List();
            foreach (var parameter in parameters)
            {
                _parameters.Add(new NamedParameter(parameter.Key, parameter.Value));
            }
            return Container.Resolve>(_parameters).ToArray();
        }
    }
    

提交回复
热议问题