Tim Hardy
Tim Hardy

Reputation: 1737

How to use factory to resolve interface using Autofac

I want to have a service like the following

public SomeService(IMongoDatabase mongoDatabase) {
    DB = mongoDatabase;
}

and I want to use a factory to resolve IMongoDatabase, just to encapsulate the IConfiguration usage

public static IMongoDatabase GetMongoDatabase(IConfiguration config)
{
    var connectionString = config.Get("SomeConnectionString");
    // MongoClient handles connection pooling internally
    var client = new MongoClient(connectionString); 
    var db = client.GetDatabase(config.Get("SomeDbName"));

    return db;
}

I can't figure out how to handle the registrations so that MongoDbFactory.GetMongoDatabase gets called whenever any class needs an IMongoDatabase. IConfiguration will be registered already.

I'd really like to just use an IMongoDatabase and not a Func<IConfiguration, IMongoDatabase> in my Service. The latter just seems way too obtuse, requiring consumers to implement steps that I should be able to implement for them.

Upvotes: 4

Views: 2010

Answers (1)

Cyril Durand
Cyril Durand

Reputation: 16192

You can register your static GetMongoDatabase factory method like this :

builder.Register(c => MongoDbFactory.GetMongoDatabase(c.Resolve<IConfiguration>)())
       .As<IMongoDatabase>();

By the way, using a static method may introduce some problem, it may be better to register the MongoDbFactory class and use it in your factory registration.

builder.RegisterType<MongoDbFactory>()
       .AsSelf();

builder.Register(c => c.Resolve<MongoDbFactory>().GetMongoDatabase())
       .As<IMongoDatabase>();

Of course, you will need to adapt the MongoDbFactory implementation to make it work - by adding a property for Configuration and adding IConfiguration to the constructor.

Upvotes: 6

Related Questions