Jack Ukleja
Jack Ukleja

Reputation: 13501

StructureMap: How to inject different named instance into constructor based on convention

I have many of the following types:

public class XDatabase : INHibernateDatabase
{
   public XDatabase(DatabaseConfiguration) { ... }
}
// etc... 

and I'm setting up StructureMap like so:

var container = new Container(x =>
    {
        x.Scan(scanner =>
                {
                    scanner.Assembly("Model.Persistence");
                    scanner.AddAllTypesOf<INHibernateDatabase>();
                });

        // The following will be generated from the app.config ConnectionStrings
        x.For<DatabaseConfiguration>()
               .Add(new DatabaseConfiguration("something"))
               .Named("XDatabase");
        // etc....
    });

container.GetAllInstances<INHibernateDatabase>();

Obviously this will not work because I have multiple instances (and no default) for DatabaseConfiguration and StructureMap doesn't know which one to choose for which INHibernateDatabase instance.

How can I tell StructureMap to use a convention so that it always picks the DatabaseConnnection instance based on a naming convention?

Upvotes: 0

Views: 1418

Answers (1)

Jack Ukleja
Jack Ukleja

Reputation: 13501

I ended up doing this using a custom IRegistrationConvention:

public class DatabaseRegistrationConvention : IRegistrationConvention
{
    public void Process(Type type, Registry registry)
    {
        if (type.CanBeCastTo<INHibernateDatabase>() && type.HasConstructors())
        {
            // In reality I get the database name via metadata
            var dbName = "databaseNameIDeterminedSomehow";

            // Outside this convention I will have procedurally add a bunch of named DatabaseConfigurations
            var configuredInstance = registry
                .For(typeof (ISchemaDeployer))
                .Use(type)
                .Ctor<DatabaseConfiguration>().IsNamedInstance(dbName);
        }
    }
}

Upvotes: 1

Related Questions