Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Autofac - resolve before build

Tags:

c#

autofac

With Unity dependency can be resolved before the container is build. Is that possible with Autofac as well? Below code demonstrates my scenario - I'd need to resolve the ICacheRepository in order to "new up" the singleton CacheHelper.

In Unity that would be simply done with container.Resolve<ICacheRepository>() in the place of ???. What about in Autofac?

var builder = new ContainerBuilder();
builder.RegisterType<CacheRepository>().As<ICacheRepository>();
var cacheHelper = new CacheHelper(???);
builder.RegisterInstance(cacheHelper).As<CacheHelper>();

Where CacheHelper class has a constructor dependency on CacheRepository.

public class CacheHelper
{
    private readonly ICacheRepository _repository;

    public CacheHelper(ICacheRepository repository)
    {
        _repository = repository;
    }
} 
like image 301
the berserker Avatar asked Dec 28 '15 21:12

the berserker


People also ask

Does Autofac use reflection?

Reflection Components RegisterType(typeof(ConfigReader)); When using reflection-based components, Autofac automatically uses the constructor for your class with the most parameters that are able to be obtained from the container.

What is AsImplementedInterfaces?

RegistrationExtensions. AsImplementedInterfaces MethodSpecifies that a type from a scanned assembly is registered as providing all of its implemented interfaces.

What is Autofac IoC?

Autofac is an IoC container for Microsoft . NET. It manages the dependencies between classes so that applications stay easy to change as they grow in size and complexity. This is achieved by treating regular . NET classes as components.


1 Answers

You should not have to resolve component during build process. Autofac is able to solve object graph dependency. In your case CacheHelper depends on ICacheRepository so you just have to register CacheHelper and ICacheRepository

var builder = new ContainerBuilder();
builder.RegisterType<CacheRepository>().As<ICacheRepository>();
builder.RegisterType<CacheHelper>().As<CacheHelper>();

When Autofac will resolve CacheHelper it will create the dependency graph and create the instance of CacheHelper with an instance ofsi ICacheRepository. If you need to have a Singleton you can tell Autofac to create only a single instance.

var builder = new ContainerBuilder();
builder.RegisterType<CacheRepository>().As<ICacheRepository>();
builder.RegisterType<CacheHelper>().As<CacheHelper>().SingleInstance();

Another solution would be register lambda expression, these registrations are called when you need it, so you can resolve things during build process :

var builder = new ContainerBuilder();
builder.RegisterType<CacheRepository>().As<ICacheRepository>();
builder.Register(c => new CacheHelper(c.Resolve<ICacheRepository>()))
       .As<CacheHelper>()
       .SingleInstance(); // It will result of having one CacheHelper whereas 
                          // ICacheRepository is declared as .InstancePerDependency 

Be careful with this solution because ICacheRepository is declared without scope the InstancePerDependency scope will be used by default. Because CacheHelper is SingleInstance only a single instance of ICacheRepository will be used which may result to bugs. See Captive Dependency for more information.

In your case, it doesn't seem like you need this kind of registration.

like image 56
Cyril Durand Avatar answered Nov 14 '22 20:11

Cyril Durand