基于构造函数参数属性使用autofac解析依赖关系

And*_*vey 4 inversion-of-control autofac

我正在使用Autofac.我想基于我应用于构造函数参数的属性注入不同的依赖实现.例如:

class CustomerRepository
{
    public CustomerRepository([CustomerDB] IObjectContainer db) { ... }
}

class FooRepository
{
    public FooRepository([FooDB] IObjectContainer db) { ... }
}

builder.Register(c => /* return different instance based on attribute on the parameter */)
       .As<IObjectContainer>();
Run Code Online (Sandbox Code Playgroud)

属性将提供数据,例如连接字符串,我可以使用它来实例化正确的对象.

我怎样才能做到这一点?

Bry*_*tts 9

听起来你想提供IObjectContainerto CustomerRepository和的不同实现FooRepository.如果是这种情况,属性可能是一个薄金属标尺.相反,我将向您展示如何使用Autofac实现多个实现.

(.ContainerScoped()为简洁而省略了这些电话.)

首先,IObjectContainer通过命名注册来为每个连接字符串注册一个版本:

builder
    .Register(c => new ObjectContainer(ConnectionStrings.CustomerDB))
    .As<IObjectContainer>()
    .Named("CustomerObjectContainer");

builder
    .Register(c => new ObjectContainer(ConnectionStrings.FooDB))
    .As<IObjectContainer>()
    .Named("FooObjectContainer");
Run Code Online (Sandbox Code Playgroud)

然后,解析存储库注册中的特定实例:

builder.Register(c => new CustomerRepository(
    c.Resolve<IObjectContainer>("CustomerObjectContainer"));

builder.Register(c => new FooRepository(
    c.Resolve<IObjectContainer>("FooObjectContainer"));
Run Code Online (Sandbox Code Playgroud)

这使得存储库没有配置信息:

class CustomerRepository
{
    public CustomerRepository(IObjectContainer db) { ... }
}

class FooRepository
{
    public FooRepository(IObjectContainer db) { ... }
}
Run Code Online (Sandbox Code Playgroud)

  • Autofac(小写f)可以支持您想要的任何类型的自定义上下文敏感构造.这是因为`Register <T>`可以接受lambda表达式(`Func <>`),你可以用Expression Trees构建lambda表达式(http://msdn.microsoft.com/en-us/library/bb397951. ASPX).这意味着您可以使用反射来构建运行自定义构造所需的任何lambda. (2认同)