我刚刚开始使用 Autofac,并有以下问题:

例如,

  • Guice 在将参数传递给构造函数时有自己的注释/方式(它们由 Guice 处理)。 autofac 有类似的功能吗?这是在类定义中,而不是在我实例化类时。
  • 当我使用类并想要获取其他类型时,是否每次都设置容器(我假设这应该是静态成员?)?
  • 最佳答案

    1) Autofac 不需要任何特定的构造函数映射。它有一个简单的规则;它将尽可能多地注入(inject),但它必须能够解析至少一个构造函数的所有参数。如果没有具有 Autofac 已知的参数类型的构造函数,您将收到运行时异常。您可以设置 Autofac 来执行构造函数或属性注入(inject),或两者的混合。公认的最佳实践是构造函数注入(inject)几乎所有内容;使用属性注入(inject)可以为您提供一个没有所有必要依赖项的对象,直到您尝试使用需要缺少依赖项的功能时,您才会知道发生了这种情况。如果依赖项很昂贵,必须是工厂范围的(每个请求的新实例)并且不总是被依赖对象使用,请考虑构造函数注入(inject)工厂方法,该方法将延迟初始化此依赖项。

    2) 如何设置 IoC 容器取决于您计划如何使用它。 IoC 容器的静态或单例实例当然是一个众所周知的用途,但许多人说这是一种反模式,因为它会使您滑下将容器用作“服务定位器”的滑坡(这使您依赖于有一个 IoC 容器来解决您的依赖项;这很好,但不应该是必需的)。普遍接受的模式是将所有依赖项和所有需要依赖项的对象都注册到容器中,并且只在对象创建的最高级别使用容器;所有其他对象将是顶级对象的依赖项,并且可以这样解析或可以通过工厂方法生成。

    我继续将我的 Autofac 容器设置为单例,因为该容器基本上存在以水合应用程序主要形式的一个实例,它本身需要向 IoC 注册的大部分依赖项,并且无论如何都可以获取其余部分它可以将它们传递给它将创建的对象。我本可以使用 IoC 注册所有对象并使用工厂方法解析子窗体,但是我会用工厂方法引用替换依赖项引用,而且我可能最终将主窗体上的各个方法连接为其他的工厂视窗。

    编辑: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
    

    关于.net - 关于 autofac 入门的一些问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/4504827/

    10-12 14:54