0

I'm following below example to create a class instance at runtime using autofac. http://autofaccn.readthedocs.io/en/latest/advanced/delegate-factories.html

But when running locally, I'm seeing an exception. I'm very new to autofac and let me know if I'm doing anything wrong here or if you need any more information.

Code structure:

public class ClassName
{
    public delegate ClassName Factory(Type1 obj1, string obj2);
    public ClassName(Type1 obj1, string obj2)
    {
        this.type1 = obj1;
        this.type2= obj2;
    }

    /*Some methods of this class that use type1 and type2*/
}

// Registration 
container.RegisterType<Type1>();
container.RegisterType<ClassName.Factory>();
container.RegisterType<ClassName>().AsSelf().InstancePerDependency();

// In some method to create an instance of ClassName
var factory = container.Resolve<Factory>(); // This is throwing the following exception.
var instance = factory(obj1Instance, "text"); // obj1Instance and "text" parameters cannot be determined at registration time.

The exception stackTrace:

Logging handled exception: Autofac.Core.DependencyResolutionException: Autofac.Core.DependencyResolutionException: An error occurred during the activation of a particular registration. See the inner exception for details. Registration: Activator = Factory (ReflectionActivator), Services = [ClassName+Factory], Lifetime = Autofac.Core.Lifetime.CurrentScopeLifetime, Sharing = None, Ownership = OwnedByLifetimeScope ---> None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'ClassName+Factory' can be invoked with the available services and parameters:
Cannot resolve parameter 'System.Object object' of constructor 'Void .ctor(System.Object, IntPtr)'. (See inner exception for details.) ---> Autofac.Core.DependencyResolutionException: None of the constructors found with 'Autofac.Core.Activators.Reflection.DefaultConstructorFinder' on type 'ClassName+Factory' can be invoked with the available services and parameters:
Cannot resolve parameter 'System.Object object' of constructor 'Void .ctor(System.Object, IntPtr)'.
   at Autofac.Core.Activators.Reflection.ReflectionActivator.GetValidConstructorBindings(IComponentContext context, IEnumerable`1 parameters)
   at Autofac.Core.Activators.Reflection.ReflectionActivator.ActivateInstance(IComponentContext context, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)
   --- End of inner exception stack trace ---
   at Autofac.Core.Resolving.InstanceLookup.Activate(IEnumerable`1 parameters)
   at Autofac.Core.Resolving.InstanceLookup.Execute()
   at Autofac.Core.Resolving.ResolveOperation.GetOrCreateInstance(ISharingLifetimeScope currentOperationScope, IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.Core.Resolving.ResolveOperation.Execute(IComponentRegistration registration, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.TryResolveService(IComponentContext context, Service service, IEnumerable`1 parameters, Object& instance)
   at Autofac.ResolutionExtensions.ResolveService(IComponentContext context, Service service, IEnumerable`1 parameters)
   at Autofac.ResolutionExtensions.Resolve[TService](IComponentContext context, IEnumerable`1 parameters)
Hulk
  • 97
  • 3
  • 16

1 Answers1

1

The problem you have is that you're trying to register a factory. Autofac understands how to resolve a delegate, but it doesn't understand how to register it.

This should work:

public class ClassName
{
    public delegate ClassName Factory(Type1 obj1, string obj2);
    public ClassName(Type1 obj1, string obj2)
    {
        this.type1 = obj1;
        this.type2= obj2;
    }
}

// Registration 
container.RegisterType<ClassName>().AsSelf().InstancePerDependency();

// In some method to create an instance of ClassName
var factory = container.Resolve<ClassName.Factory>();
var instance = factory.Invoke(obj1Instance, "text");

Edit:

After running this myself I got the same exception but quickly realised what the issue was. Quoting autofac's entry on delegate factories I saw this:

By default, Autofac matches the parameters of the delegate to the parameters of the constructor by name

The names of my constructor's parameters and my delegates' parameters didn't match which leads autofac to try and resolve the object by type, and since you haven't (and shouldn't unless you know you want to, and even so, you shouldn't) registered a string autofac's Autofac.Core.Activators.Reflection.DefaultConstructorFinder fails.

Community
  • 1
  • 1
Maximo Dominguez
  • 2,075
  • 18
  • 35
  • No, I'm still facing the same exception even after removing the line container.RegisterType(); Is there something else that I'm missing here? – Hulk Feb 06 '18 at 03:46
  • Seeing this exception to be precise if I remove the line:The requested service 'ClassName+Factory' has not been registered – Hulk Feb 06 '18 at 03:58
  • But as shown in the above example, I'm using same parameter names for delegate and my constructor. – Hulk Feb 06 '18 at 15:44
  • Yeah I know, but I figured —based on the exception mentioning a constructor with an `object` and an `int`, and that those type names obviously do not belong in any codebase— that the extract of code you posted in this question is the result of modifying your code in order to post it to stack overflow, which you might have partially fixed in the process. – Maximo Dominguez Feb 06 '18 at 15:57