关于gettig的一些问题始于autofac

Gur*_*epS 4 .net autofac

我刚刚接触到Autofac,并提出以下问题:

  1. 例如,当你将参数传递给构造函数时,Guice有自己的注释/方法(它们由Guice处理).autofac做类似的事吗?这是在类定义中,而不是在我实例化类时.

  2. 当我使用类并想要获得其他类型时,我是否每次都设置容器(我假设这应该是静态成员?)?

Kei*_*thS 6

1)Autofac不需要构造函数的任何特定映射.它有一个简单的规则; 它将尽可能多地注入,但它必须能够解析至少一个构造函数的所有参数.如果没有构造函数具有Autofac都知道的参数类型,那么您将获得运行时异常.您可以设置Autofac来执行构造函数或属性注入,或两者的混合.公认的最佳实践是建造者注入几乎所有东西; 使用属性注入可以为您提供一个没有所有必需依赖项的对象,在您尝试使用需要缺少依赖项的功能之前,您不会知道这些依赖项.如果依赖项很昂贵,则必须是工厂作用域(每个请求的新实例)并且并非总是由依赖对象使用,请考虑构造函数 - 注入将懒惰地初始化此依赖项的工厂方法.

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
Run Code Online (Sandbox Code Playgroud)