2

I'm having issues with Autofac's (version 3.0.2) resolution of Funcs. Why is Autofac able to return Funcs for types which it cannot resolve? It seems Autofac is doing the dependency resolution when the func is executed which seems incorrect and should be done when the Func is created (not creating a Foo type but ensuring its constructor may be called with the known registered types).

using System;
using Autofac;
using NUnit.Framework;

namespace AutofacTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var builder = new ContainerBuilder();
            builder.RegisterType<Foo>().AsSelf().AsImplementedInterfaces();
            var container = builder.Build();

            //var foo = container.Resolve<IFoo>(); //Throws because the int arg can't be resolved (as it should)
            Assert.True(container.IsRegistered<Func<int, IFoo>>()); //This is valid and makes sense
            var fooFunc = container.Resolve<Func<int, IFoo>>();
            var foo = fooFunc(9);

            //Assert.False(container.IsRegistered<Func<string, IFoo>>()); //Why is this true?
            var badFooFunc = container.Resolve<Func<string, IFoo>>(); // Why doesn't Autofac throw here?
            var badFoo = badFooFunc(string.Empty); // Autofac throws here
        }

    }

    interface IFoo { }
    public class Foo : IFoo 
    {
        public string ArgStr { get; set; }
        public Foo(int arg)
        {
            this.ArgStr = arg.ToString();
        }
    }

}
smith324
  • 13,020
  • 9
  • 37
  • 58
  • This type of questions: like why is something implemented this or that way are not good fit on SO... you are better asking this on the discussion group: https://groups.google.com/forum/#!forum/autofac – nemesv Jul 02 '13 at 20:14
  • This is a usage question, and according to the group: "If you have a usage/support question, we'd prefer you to describe it and use the 'autofac' tag on Stack Overflow" – smith324 Jul 02 '13 at 20:55
  • What are you trying to achieve? – Andrew Savinykh Jul 07 '13 at 22:48
  • I'd like to verify that Autofac can resolve all dependencies for a given class, but this issue prevents me from doing that. – smith324 Jul 08 '13 at 01:02

2 Answers2

2

According to this code, it seems that Func<> is actually a compiled call to Resolve using TypedParameter. As the call is not made until you call the Func<>, it is not able to detect whether the call is valid and parameters can be mapped.

I am not sure whether Autofac provides an easy way to verify possibility of resolve without actually resolving — but this is definitely not a common functionality and so it is unsurprising that Func<> does not include that.

However, given that Autofac is open source, you can definitely look into adding that functionality if you are interested.

Andrey Shchekin
  • 21,101
  • 19
  • 94
  • 162
1

Having a function resolve it's dependencies at run time is the definition of dependency injection and inversion of control. If it did not do this it would not be IOC.

Hogan
  • 69,564
  • 10
  • 76
  • 117
  • I think you got confused by terminology, which is easy with IOC related topics. In the OP source code this particular line `var badFooFunc = container.Resolve>();` IS the resolution and it IS at runtime. Still for some reason it succeeds and yields unusable result. – Andrew Savinykh Jul 07 '13 at 23:32