Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autofac. How to get caller class Type?

Suppose we have two classes with same constructor Injectable dependency:

public class FirstClass
{
    public FirstClass(ISomeDependency someDependency)
    { }
}

public class SecondClass
{
    public SecondClass(ISomeDependency someDependency)
    { }
}

Now we have a registration for ISomeDependency:

builder.Register(x =>
        {
            string key = GetKeyFromCurrentHttpRequest();
            // if "Caller" is "FirstClass" return new Dependency(key);
            // else return new Dependency("defaultKey");
        }).As<ISomeDependency>();

Note: This is a simplified use case. The real scenario is much more complicated.

1. How to get "Caller" type which tryies to resolve ISomeDependency?

2. Is there a better way design for such situations?

like image 753
Cristian E. Avatar asked Jan 29 '15 17:01

Cristian E.


1 Answers

You can use delegate factories do achieve your goal. The only drawback is the FirstClass and SecondClass cannot use ISomeDependency as parameter.

You can try this code in a console application (just add Autofac dependency).

using System;
using Autofac;

namespace test
{
    class MainClass
    {
        public static void Main(string[] args)
        {
            ContainerBuilder builder = new ContainerBuilder ();
            builder.RegisterType<SomeDependency>().As<ISomeDependency>();
            builder.RegisterType<FirstClass>();
            builder.RegisterType<SecondClass>();
            var container = builder.Build();

            var dummy = container.Resolve<FirstClass>();
            var dummy2 = container.Resolve<SecondClass>();
        }

        public interface ISomeDependency
        {
        }

        public class SomeDependency : ISomeDependency
        {
            public delegate ISomeDependency Factory(string value);
            private readonly string _value;

            public SomeDependency(string value)
            {
                _value = value;
                Console.WriteLine("Value = " + _value);
            }
        }

        public class FirstClass
        {
            private ISomeDependency _dependency;

            public FirstClass(SomeDependency.Factory factory)
            { 
                _dependency = factory.Invoke("my value");
            }
        }

        public class SecondClass
        {
            private ISomeDependency _dependency;

            public SecondClass(SomeDependency.Factory factory)
            {
                _dependency = factory.Invoke("my value 2");
            }
        }
    }
}
like image 96
hugo Avatar answered Nov 11 '22 20:11

hugo