Should I explicitly bind regular classes with Autofac?

It seems I am doing this in my code:

public class ActionsModule : Module { protected override void Load(ContainerBuilder builder) { base.Load(builder); builder.Register(c => LogManager.GetCurrentClassLogger()).As<ILog>().InstancePerDependency(); // Autofac doesn't seem to be able to inject things without explicit binding builder.RegisterType<ComboActions>().As<ComboActions>().InstancePerHttpRequest(); builder.RegisterType<AppActions>().As<AppActions>().InstancePerHttpRequest(); } } } 

If the "action" class is the class that I need to enter in my controller, and it has various other dependencies.

It seems a bit garbage. Why can't autofac decide that a class has a constructor with dependencies that are already satisfied and automatically instantiate?

I mean, if class A requires input of class B, and class B requires enough C, D, E, etc., I think you do not want to go through the entire dependency chain to see if you can make the class at runtime .... but if class A is directly dependent on C and D, which are explicitly related, then of course, what is the trivial case?

Am I missing something? I don't seem to see any documentation for this ...

+6
source share
2 answers

AFAIK, Autofac requires that each necessary type is registered in the container, but this does not mean that you must do each separately. Almost 99% of my registrations are handled by adding this attribute to the type:

 [AttributeUsage(AttributeTargets.Class)] public class AutoRegisterAttribute : Attribute { } 

So, for example, you will have

 [AutoRegister] class ComboActions { 

And then I register them as follows:

 public class AutoScanModule : Module { private readonly Assembly[] _assembliesToScan; public AutoScanModule(params Assembly[] assembliesToScan) { _assembliesToScan = assembliesToScan; } protected override void Load(ContainerBuilder builder) { builder.RegisterAssemblyTypes(_assembliesToScan) .Where(t => t.GetCustomAttributes(typeof (AutoRegisterAttribute), false).Any()) .AsSelf() .AsImplementedInterfaces() .InstancePerLifetimeScope(); } } 

As I said, this covers most of my registrations, and then I usually have to worry about things like third-party manufacturers, open generics, and decorators.

EDIT: Answer the answer from Kaleb , which proves that I am wrong. A cool feature that I never knew about!

+2
source

You do not need to register each type. Autofac provides AnyConcreteTypeNotAlreadyRegisteredSource that will automatically capture a particular type if you have not registered a registration yet.

For instance:

 var builder = new ContainerBuilder(); builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource()); var container = builder.Build(); ... var myConcreteType = container.Resolve<MyConcreteType>(); 

Sources allow more complex things, such as automatically mocking objects for interfaces and class-based abstract dependencies.

+20
source

Source: https://habr.com/ru/post/919645/


All Articles