Some gettig questions started with autofac

I just deal with Autofac and ask the following questions:

  • Guice, for example, has its own annotations / methods when you pass parameters to constructors (they are handled by Guice). Does autofac really do something like this? This is a class definition, not when I instantiate a class.

  • When I use classes and want to get other types, do I set up the container each time (do I assume it should be a static member?)?

+4
source share
1 answer

1) Autofac does not require any specific mapping of constructors. It has one simple rule; it will enter as much as it can, but it should be able to resolve all parameters of at least one constructor. If there are no constructors with parameter types that are all known by Autofac, you will get an exception at runtime. You can configure Autofac to install a constructor or property or a hybrid of both. The accepted best practice is for the constructor to introduce almost everything; using property injection can give you an object that does not have all the necessary dependencies that you donโ€™t know about, until you try to use functionality that requires no dependency. If the dependency is expensive, it must be factory -scoped (a new instance for each request) and not always used by the dependent object, consider a constructor injecting a factory method that lazily initializes this dependency.

2) How to configure the IoC container depends on how you plan to use it. A static or single instance of an IoC container is certainly well-known, but many say itโ€™s an anti-pattern, because it leads you to a slippery slope of using the container as a โ€œservice locatorโ€ (which makes you dependent on having an IoC container to resolve your dependency Itโ€™s nice, but not necessary). A common feature is the registration of all dependencies and all objects that need a dependency on the container, and the use of the container only at the highest level of creation of the object; all other objects will be dependent on the top-level object and either resolved as such, or can be obtained using the factory method.

I went ahead and installed the Autofac container as a singleton, since the container basically exists to remove an instance of the main form of the application, which itself needs most of the dependencies registered in IoC, and gets the rest anyway so that they can pass them to objects that he will create. I could register all objects using IoC and resolved child forms using factory methods, but I would replace dependency links with factory methods references, and I could probably connect individual methods in the main form as factories for other windows.

EDIT: sample code for 1):

public interface IDoSomething {...} public interface IDoSomethingElse {...} //the implementations don't have to be the same class, of course; //this is for simplicity public class DoTwoThings: IDoSomething, IDoSomethingElse {...} public class ExpensiveObject {...} public class DependentClass { public DependentClass(IDoSomething aDoer, IDoSomethingElse anotherDoer) {...} } public class DependsOnExpensiveObject { private Func<ExpensiveObject> Factory; private ExpensiveObject instance; public DependsOnExpensiveObject(Func<ExpensiveObject> factoryMethod) { Factory = factoryMethod; } public bool HasInstance { get{ return instance != null; } } public void ForceInitialize() { instance = Factory(); } } ... //In your main method, or wherever var builder = new ContainerBuilder() builder.RegisterType<DoTwoThings>().As<IDoSomething>(); builder.Register<DependentClass>(); var container = builder.Build(); //This line of code will throw at runtime b/c IDoSomethingElse //does not have an implementation registered with the container. container.Resolve<DependentClass>(); //Now we'll register the other dependency; //dependencies can be registered and overwritten at will builder.RegisterType<DoTwoThings>().As<IDoSomethingElse>(); builder.Update(container); //This line will succeed now that we have a registration for IDoSomethingElse container.Resolve<DependentClass>(); builder.RegisterType<ExpensiveClass>(); builder.RegisterType<DependsOnExpensiveClass>(); builder.Update(container); //Autofac will provide a delegate that resolves an ExpensiveObject var dependent = container.Resolve<DependsOnExpensiveClass>(); if(!dependent.HasInstance) //HasInstance returns false dependent.ForceInitialize(); Console.WriteLine(HasInstance); // True 
+6
source

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


All Articles