Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
596 views
in Technique[技术] by (71.8m points)

inversion of control - Resolve dependency with autofac based on constructor parameter attribute

I'm using Autofac. I want to inject a different implementation of a dependency based on an attribute I apply to the constructor parameter. For example:

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>();

The attributes will be providing data, such as a connection string, which I can use to instance the correct object.

How can I do this?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

It sounds like you want to provide different implementations of IObjectContainer to CustomerRepository and FooRepository. If that is the case, attributes might be a thin metal ruler. Instead, I'll show you how I would implement multiple implementations with Autofac.

(Calls such as .ContainerScoped() have been left out for brevity.)

First, register a version of IObjectContainer for each connection string by naming the registrations:

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

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

Then, resolve the specific instances in the repository registrations:

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

builder.Register(c => new FooRepository(
    c.Resolve<IObjectContainer>("FooObjectContainer"));

This leaves the repositories free of configuration information:

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

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...