Search code examples
c#autofac

Autofac requires that the factory has exactly the same name as the constructor parameter?


Here's something I don't quite understand, I have the following classes

public class ParametersContentVM<T>
{
        //here's the factory, note that the internalData variable name is the same across factory and the constructor method, note the difference between "data" and "internalData"
        public delegate ParametersContentVM<T> Factory(IParametersDefinition<T> definition, T data, string projDir);

        public ParametersContentVM(IParametersDefinition<T> definition, T internalData,
           string projDir)
}

 public class ParametersVMFactory 
 {  
        public ParametersVMFactory(ParametersContentVM<object>.Factory factory)
        {
            
            _factory = factory;
        }

public ParametersContentVM Create(IParametersDefinition<object> parametersDefinition, object param, string projectDir)
        {
  
            return _factory(parametersDefinition, param, projectDir);
        }

 }

If I resolve the and call Create, ie:

var parametersCommand = container.Resolve<ParametersVMFactory >();
parametersCommand.Create(..);

Then I will get an AutofacException. But I can fix the issue by changing the data variable name in the Factory to internalData.

That's what I don't understand, how can the argument be name dependent, is it documented in the Autofac documentation?


Solution

  • Yes, it is documented in the Autofac documentation.

    Check the Create a Delegate section in Delegate Factories topic.

    By default, Autofac matches the parameters of the delegate to the parameters of the constructor by name. If you use the generic Func relationships, Autofac will switch to matching parameters by type. The name matching is important here - it allows you to provide multiple parameters of the same type if you want, which isn’t something the Func implicit relationships can support. However, it also means that if you change the names of parameters in the constructor, you also have to change those names in the delegate.

    So, you

    • either use a Delegate type with matching parameter names
      multiple parameters can have the same type.
    • or use a Func<> generic delegate with matching parameter types.
      each parameter must be of different types.